更改 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
打印更改和未更改的记录
这将适用于所有输入行以及 defaults
和 string
的所有不包含反斜杠的值(如果有的话,这是一个简单的调整):
$ 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
我需要更改文件中的字符串,该字符串在每一行都重复,但我只需要更改几行(而不是所有行)。 比方说,/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
打印更改和未更改的记录
这将适用于所有输入行以及 defaults
和 string
的所有不包含反斜杠的值(如果有的话,这是一个简单的调整):
$ 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