这就是我想做的。例如,我的文件包含许多行说:
ABC,2,4 DEF,5,6 GHI,8,9
我想复制第二行,替换子字符串EF(所有出现的字符串),使其为XY,并将该行添加回文件,使文件如下所示:
ABC,2,4 DEF,5,6 GHI,8,9 DXY,5,6
如何在Bash中实现这一点?编辑:我想做一般的,不一定是第二行。我想grep EF,并做任何行返回的替代。
nbewdwxp1#
下面是一个简单的Awk脚本。
awk -F, -v pat="EF" -v rep="XY" 'BEGIN { OFS=FS } $1 ~ pat { x = $1; sub(pat, rep, x); y = $0; sub($1, x, y); a[++n] = y } 1 END { for(i=1; i<=n; i++) print a[i] }' file
-F ,表示使用逗号作为输入字段分隔符(内部变量FS),在BEGIN块中,我们也将其设置为输出字段分隔符(OFS)。如果第一个字段与模式匹配,我们将第一个字段复制到x中,用rep替换pat,然后用新的结果替换整行$0的第一个字段,并将其添加到数组a中。1是表示“打印当前输入行”的简写。最后,在END块中,我们将收集到的值输出到a中。这可以通过硬编码模式和替换来简化,但是我认为模块化更有用,这样您就可以插入任何需要的值。虽然这一切都可以在本地Bash中完成,但它往往会有点折磨人;花30分钟左右的时间对Awk有一个基本的了解是非常值得的,也许还可以参考while read loop extremely slow compared to cat , why?,它解释了使用外部工具(如Awk)而不是纯粹的Bash解决方案的部分理由。
-F ,
FS
BEGIN
OFS
x
rep
pat
$0
a
1
END
while read
cat
x759pob22#
可以使用sed命令:
sed
sed ' /EF/H # copy all matching lines ${ # on the last line p # print it g # paste the copied lines s/EF/XY/g # replace all occurences s/^\n// # get rid of the extra newline }'
作为一行程序:
sed '/EF/H;${p;g;s/EF/XY/g;s/^\n//}' file.csv
luaexgnf3#
如果ed可用/可接受,则如下所示:
ed
#!/bin/sh ed -s file.txt <<-'EOF' $kx g/^.*EF.*,.*/t'x 'x+;$s/EF/XY/ ,p Q EOF
或者是单行的。
printf '%s\n' '$kx' "g/^.*EF.*,.*/t'x" "'x+;\$s/EF/XY/" ,p Q | ed -s file.txt
Q
w
,p
3条答案
按热度按时间nbewdwxp1#
下面是一个简单的Awk脚本。
-F ,
表示使用逗号作为输入字段分隔符(内部变量FS
),在BEGIN
块中,我们也将其设置为输出字段分隔符(OFS
)。如果第一个字段与模式匹配,我们将第一个字段复制到
x
中,用rep
替换pat
,然后用新的结果替换整行$0
的第一个字段,并将其添加到数组a
中。1
是表示“打印当前输入行”的简写。最后,在
END
块中,我们将收集到的值输出到a
中。这可以通过硬编码模式和替换来简化,但是我认为模块化更有用,这样您就可以插入任何需要的值。
虽然这一切都可以在本地Bash中完成,但它往往会有点折磨人;花30分钟左右的时间对Awk有一个基本的了解是非常值得的,也许还可以参考
while read
loop extremely slow compared tocat
, why?,它解释了使用外部工具(如Awk)而不是纯粹的Bash解决方案的部分理由。x759pob22#
可以使用
sed
命令:作为一行程序:
luaexgnf3#
如果
ed
可用/可接受,则如下所示:或者是单行的。
Q
更改为w
。,p
以使输出静音。