我有一个带有 [pipe] 分隔符的输入字符串|
,并且喜欢按&
字符替换空字符串第三列和第五列。
输入文件:
a a|b b|c c|d d|e e
f f|g g|h h|i i|j j
输出文件:
a a|b b|c&c|d d|e&e
f f|g g|h&h|i i|j&j
您可以看到之间的空格cc, ee, hh and jj
被替换为&
我有一个替代解决方案,其中涉及使用读取文件while 循环并通过使用cut
基于分隔符的命令并将其存储在基于位置的变量中,并使用“&”替换空格,sed
并将所有分割的变量附加到一个变量中,并将其附加到一个新文件中。是否有一个命令可以用来实现这一目标?
答案1
用于awk
此:
awk -F\| '{gsub(" ","\\&",$3); gsub(" ","\\&",$5)}1' OFS=\| infile.txt
,告诉“awk”字段
-F\|
由管道分隔|
(它是由\
shell 转义的,不要将其解释为pipeline stdin
,我们可以使用-F"|"
或-F'|'
)。这
gsub("regexp","replacement"[, INDEX])
用于将" "
(空格)替换为&
索引(列)中的文字的语法$3
,$5
下面显示了基于|
分隔符的每个索引位置。a a|b b|c c|d d|e e ^^^|^^^|^^^|^^^|^^^ $1 |$2 |$3 |$4 |$5
阅读更多关于为什么我们
\\&
两次逃到那里?!1
结尾处用什么awk '{...}1'
?这是 awk 的默认打印操作控件。阅读更多详细信息再次
OFS=\|
返回或打印具有指定分隔符的字段|
。
答案2
你可以做
sed 's/\(|[^| ]*\) */\1\&/4;s//\1\&/2'
以你为例。解释:
|[^| ]*
搜索字段分隔符以及该列中的所有非空格。它被分组为\(\)
,因此稍后可以将其复制到替换中\1
。然后一个或多个空格将被 替换&
,需要在替换字符串中转义。4
将其应用于第四次出现(即第五列)的方法。然后2
对第三列重复此操作。您不需要通过提供空模式来重复该模式。
如果列中可以有多个空格或根本没有空格,则情况会更复杂。然后最好使用不同的工具,例如awk
.
另一方面,如果您知道每列中始终有一个空格,请执行一个简单的操作
sed 's/ /\&/5;s//\&/3'
答案3
perl -aF'(\|)' -lne 's/\h/&/ for @F[2*2,2*4]; print @F' input_file
结果
a a|b b|c&c|d d|e&e
f f|g g|h&h|i i|j&j
在职的
拆分管道上的当前记录|
,并在字段中包含分隔符。因此,第3场和第5场变成2*2和2*4场。
\h
对于这两个字段,我们用文字替换水平空白&
。完成后,只需打印字段即可。