更改 ASCII 文件中精确滚动的精确单词

Change an exact word on exact roll in ASCII file

我需要更改文件中的字符串,该字符串在每一行都重复,但我只需要更改几行(而不是所有行)。 比方说,/etc/fstab 文件:

/dev/mapper/rhel-root            /                       xfs     defaults        0 0
/dev/mapper/rhel-boot            /boot                   ext4    defaults        1 2
/dev/mapper/rhel-home            /home                   ext3    defaults        1 2
/dev/mapper/rhel-var             /var                    ext3    defaults        1 2
/dev/mapper/workvg-swaplv        swap                    swap    defaults        0 0

如何将 /home 和 /var 条目的 "defaults" 字符串更改为 "string"? 我试过的想法是使用了很多 grep|sed|exargs 等的组合,但它没有按预期工作:)

echo $(egrep "/var | /home" fstab | awk '{ print }') | xargs -I '{}' sed 's/{}/string/' fstab

有人可以给我一些关于这方面的想法吗? 提前谢谢你们!

$ sed -E '/\/(home|var)/ s/defaults/string/' fstab
/dev/mapper/rhel-root            /                       xfs     defaults        0 0
/dev/mapper/rhel-boot            /boot                   ext4    defaults        1 2
/dev/mapper/rhel-home            /home                   ext3    string        1 2
/dev/mapper/rhel-var             /var                    ext3    string        1 2
/dev/mapper/workvg-swaplv        swap                    swap    defaults        0 0
  • -E 使用扩展正则表达式
  • /\/(home|var)/ 这是只匹配那些带有 /home/var
  • 的行
  • s/defaults/string/ 用替换字符串替换所需的模式

编辑:

为了更稳健的匹配:

sed -E '/^\S+\s+\/(home|var)\b/ s/^((\S+\s+){3})defaults\b/string/' fstab

这将检查第 2 列中 /home/var 的完全匹配,并替换第 4 列中 defaults 的完全匹配

\b 检查单词边界,\s 匹配空格,\S 匹配非空格

$ awk '/\/var/ || /\/home {sub(/defaults/, "string")} 1'` /etc/fstab
  • /\/var || /\/home if 关键字在记录中
  • sub{/defaults/, "string") 将第一个 "defaults" 替换为 "string"
  • 1 打印更改和未更改的记录

这将适用于所有输入行以及 defaultsstring 的所有不包含反斜杠的值(如果有的话,这是一个简单的调整):

$ cat tst.awk
BEGIN { split(entries,t); for (i in t) tgts["/"t[i]] }
( in tgts) && match([=10=],/^((\S+\s+){3})(\S+)(\s.*)$/,a) && (a[3]==old) { [=10=] = a[1] new a[4] }
{ print }

$ awk -v entries="home var" -v old="defaults" -v new="string" -f tst.awk file
/dev/mapper/rhel-root            /                       xfs     defaults        0 0
/dev/mapper/rhel-boot            /boot                   ext4    defaults        1 2
/dev/mapper/rhel-home            /home                   ext3    string        1 2
/dev/mapper/rhel-var             /var                    ext3    string        1 2
/dev/mapper/workvg-swaplv        swap                    swap    defaults        0 0

它使用 GNU awk 作为第三个参数来 match(),其他 awk 将使用 substr()。

awk '/home|var/{sub(/defaults/,"string  ")}1' file

/dev/mapper/rhel-root            /                       xfs     defaults        0 0
/dev/mapper/rhel-boot            /boot                   ext4    defaults        1 2
/dev/mapper/rhel-home            /home                   ext3    string          1 2
/dev/mapper/rhel-var             /var                    ext3    string          1 2
/dev/mapper/workvg-swaplv        swap                    swap    defaults        0 0