2

我正在处理一些包含“||||”的字段分隔符的文本:

substring1||||substring2

子字符串也可能包含空格。我想根据分隔符“||||”拆分这些字符串,但我找不到合适的方法来做到这一点。我尝试了以下命令:

echo "substring1||||substring2" | awk '{split($0,a,"||||"); a[2],a[1]}'

实际上,如果我只有一个“|”,则该命令有效 作为分隔符。但我的问题是我有多个管道字符。

我也试过

a=($(echo "substring1||||substring2" | sed -e "s/||||/\n/g")) 

如果子字符串不包含空格,它可以正常工作。但由于子字符串可能包含空格,因此它们也在空格上被拆分,这是不希望的。

任何想法?

4

4 回答 4

9

使用正则表达式作为输入字段分隔符,例如:

awk -F'[|]{4}' '{ printf "Field 1 -> %s\nField 2 -> %s\n", $1, $2 }' infile

假设infile内容:

sub string 1||||sub string2

它产生:

Field 1 -> sub string 1
Field 2 -> sub string2

编辑awk:对于不接受{n}语法使用的旧版本,-F'[|][|][|][|]'或者-F'[|]+',例如:

awk -c -F'[|]+' '{ printf "Field 1 -> %s\nField2 -> %s\n", $1, $2 }' infile

另外--re-interval,感谢blue的评论:

awk -c --re-interval -F'[|]{4}' '{ printf "Field 1 -> %s\nField2 -> %s\n", $1, $2 }' infile 
于 2013-06-09T10:17:20.083 回答
3

GNU awk您可以描述一个字段正在使用什么FPAT,而不是描述字段分隔符是什么:

$ echo "substring1||||substring2" | awk '{print $1,$2}' FPAT='[^|]+' OFS='\n'
substring1
substring2 
于 2013-06-09T13:00:52.617 回答
2

splitin使用的模式awk实际上是正则表达式,因此||||实际上可能是 4 个交替运算符而不是 4 个文字竖线(我不确定,因为在某些条件下,|可以是文字竖线。

要匹配竖线,请使用\|[|]。所以对于你想要的,你可以这样做

awk '{ split($0, a, /\|+/); print a[2],a[1]}' file

注意我使用/.../(正则表达式常量)来包围模式而不是引号(动态正则表达式)。有关gawk 手册中差异的一些细节。


如果要将第 1 列写入一个文件,将第 2 列写入另一个文件,则可以全部完成awk(我使用的是 Birei 的方式,因为它更简洁)。

awk -F'[|]+' '{c1 = c1 $1 "\n"; c2 = c2 $2 "\n"} END {printf c1 >"file1"; printf c2 >"file2"}' input_file

这会将第 1 列条目附加到c1由换行符分隔的第 2 列到c2. 然后在处理输入文件后将两者打印到单独的文件中。

笔记:

  1. 串联awk通过将字符串并排放置来起作用。
  2. 我使用printfwhich 不附加换行符,因为我们在c1and的末尾已经有一个额外的换行符c2
  3. awk 脚本中除 betweenprintf及其参数外的所有水平间距都是可选的。

旁注: 的值-F实际上是一个动态正则表达式,所以相当于'[|]+'is '\\|+'

于 2013-06-09T11:53:07.903 回答
-3

尝试使用 sed 和 tr ...看看它是否有帮助!

输入.txt

sub string 1||||sub string 2
            or
 substring1||||substring2

代码

  sed 's/||*/%~%/g' Input.txt| tr "%~%" '\n' | sed '/^$/d'

笔记

使用任何表达式,如 "%~%" ...。任何不会出现在您的文本文件中的表达式(就像我使用过的那样)...并使用 sed 和 tr 替换它...

于 2013-06-09T10:28:14.053 回答