给定一个竖线分隔的文件:
1|123|A |Normal Behaviour Exhibit
2|345|B|Embedded|delimiter
3|678|D|dimension 1"
4| | | | nvalue
5| | | |Missing cvalue
我需要使用 sed 或 awk 等 Unix 工具来替换所有出现| |
的||
。符号之间可以有多个空格,|
如上面第 4 行所示。
预期输出:
1|123|A |Normal Behaviour Exhibit
2|345|B|Embedded|delimiter
3|678|D|dimension 1"
4|||| nvalue
5||||Missing cvalue
我尝试使用以下sed
命令,但没有达到预期的结果:
sed 's/| *|/||/g' S.txt > S1.txt
1|123|A |Normal Behavior Exhibit
2|345|B|Embedded|delimiter
3|678|D|dimension 1"
4|| || nvalue
5|| ||Missing cvalue
答案1
使用任何 sed:
$ sed 's/| *|/||/g; s/| *|/||/g' file
1|123|A |Normal Behaviour Exhibit
2|345|B|Embedded|delimiter
3|678|D|dimension 1"
4|||| nvalue
5||||Missing cvalue
或使用任何 awk:
$ awk '{while( sub(/\| +\|/,"||") );} 1' file
1|123|A |Normal Behaviour Exhibit
2|345|B|Embedded|delimiter
3|678|D|dimension 1"
4|||| nvalue
5||||Missing cvalue
答案2
使用perl
,您可以将所有替换|<spaces>
为|
,前提是它们后面跟着|
使用(?=...)
前瞻正则表达式运算符:
perl -pe 's/\| +(?=\|)/|/g' your-file
perl
还有一个-i
用于i
n 处编辑的选项。
答案3
使用awk
:
awk 'BEGIN{OFS=FS="|"}{for (i=1; i<=NF; i++) if ($i ~ /^ +$/) $i=""}1' file
1|123|A |Normal Behaviour Exhibit
2|345|B|Embedded|delimiter
3|678|D|dimension 1"
4|||| nvalue
5||||Missing cvalue
答案4
第一个匹配消耗了末端需要成为第二个匹配的一部分的管道。
我只是循环替换,直到不再有匹配项为止,而不是使用修饰符g
:
sed -e ': loop' -e 's/| *|/||/' -e 't loop'
请注意,我在模式中使用了两个空格,因此||
不匹配。