shell Grep文件中的一行,替换子字符串并将该行追加到原始文件中,

ac1kyiln  于 2023-01-26  发布在  Shell
关注(0)|答案(3)|浏览(175)

这就是我想做的。
例如,我的文件包含许多行说:

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,并做任何行返回的替代。

nbewdwxp

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解决方案的部分理由。

x759pob2

x759pob22#

可以使用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
luaexgnf

luaexgnf3#

如果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以使输出静音。

相关问题