繁体   English   中英

拆分字符串(例如使用bash)但跳过部分字符串

[英]split string (e.g. with bash) but skip part of it

如何用bash(awk,sed,无论如何)拆分以下字符串:

在:

a,b,[c, d],e

输出:

a
b
[c, d]
e

尝试1)

$IFS=',' read -a tokens <<< "a,b,[c, d], e"; echo ${tokens[@]}
a b [c d] e

尝试2)

$ IFS=',' 
$ line="a,b,[c, d], e"
$ eval x=($line)
$ echo ${x[1]}
b
$ echo ${x[0]}
a
$ echo ${x[2]}
[c  d]

But not ','!

这只是一般CSV问题的一个特定实例,即识别引号内的逗号与引号之外的逗号不同,以便用一个其他字符替换任何一个(例如; )。 这个惯用的awk解决方案(除了在GNU awk中使用FPAT)是:

在引号内替换:

$ echo 'a,b,"c, d",e' | awk 'BEGIN{FS=OFS="\""} {for (i=2;i<=NF;i+=2) gsub(/,/,";",$i)}1'
a,b,"c; d",e

在引号之外替换:

$ echo 'a,b,"c, d",e' | awk 'BEGIN{FS=OFS="\""} {for (i=1;i<=NF;i+=2) gsub(/,/,";",$i)}1'
a;b;"c, d";e

在你的情况下,分隔符是[...]而不是"..." ,替换字符是换行符而不是分号,但它基本上是同一个问题:

在“引号”(方括号)之外替换:

$ echo 'a,b,[c, d],e' | awk 'BEGIN{FS="[][]"; OFS=""} {for (i=1;i<=NF;i+=2) gsub(/,/,"\n",$i)}1'
a
b
c, d
e

请注意,方括号不见了,因为我将OFS设置为空白字符,因为没有1个单独的FS字符可供使用。 如果你确实需要它们,你可以用它来取回它们:

$ echo 'a,b,[c, d],e' | awk 'BEGIN{FS="[][]"; OFS=""} {for (i=1;i<=NF;i++) if (i%2) gsub(/,/,"\n",$i); else $i="["$i"]"}1'
a
b
[c, d]
e

但是你没有机会,因为他们的目的是将包含逗号的文本分组,现在由换行处理的是字段分隔符而不是逗号。

你可以使用这个grep:

grep -Po '([a-z]|\[[a-z], [a-z]\])'
           ^^^^^ ^^^^^^^^^^^^^^^^ 

看到:

$ echo "a,b,[c, d],e" | grep -Po '([a-z]|\[[a-z], [a-z]\])'
a
b
[c, d]
e

也就是说,使用grep仅打印(因此-o ,仅匹配), [az]字母或[ + [az], [az] + ]

或者您也可以选择打开[和关闭, [az]]块:

$ echo "a,b,[c, d],e" | grep -Po '(\[)?[a-z](, [a-z]\])?'
a
b
[c, d]
e

匹配以[并以]结尾的所有内容: \\[[^][]*\\] 然后匹配任何不是逗号的内容: [^,]\\+

echo 'a,b,[c, d],e' | grep -o -e '\[[^][]*\]' -e '[^,]\+'

输出:

a
b
[c, d]
e

echo "a,b,[c, d],e" | grep -o '\\[.*\\]\\|[^,]*'

输出:

a
b
[c, d]
e

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM