我需要从文件中更改一个字符串,该文件在每一行都会重复,但我只需要为几行(不是所有行)更改它。 可以说,/ 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条目? 我认为我认为使用了很多grep | sed | exargs等的组合,但它并没有像预期的那样工作:)
echo $(egrep "/var | /home" fstab | awk '{ print $4}') | xargs -I '{}' sed 's/{}/string/' fstab
有人能给我一些关于此事的想法吗? 提前谢谢你们!
答案 0 :(得分:2)
$ 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/\1string/' fstab
这会检查第二列中/home
或/var
的完全匹配,并替换第四列中defaults
的完全匹配
\b
检查字边界,\s
匹配空格,\S
匹配空白
答案 1 :(得分:1)
这对于所有输入行以及defaults
和string
的所有不包含反斜杠的值都是可靠的(如果你有这些,可以轻松调整):
$ cat tst.awk
BEGIN { split(entries,t); for (i in t) tgts["/"t[i]] }
($2 in tgts) && match($0,/^((\S+\s+){3})(\S+)(\s.*)$/,a) && (a[3]==old) { $0 = 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为第3个arg匹配(),其他awk将使用substr()。
答案 2 :(得分:0)
$ awk '/\/var/ || /\/home {sub(/defaults/, "string")} 1'` /etc/fstab
/\/var || /\/home
如果记录中的关键字sub{/defaults/, "string")
替换第一个"默认值"用"字符串" 1
打印已更改且未更改的记录答案 3 :(得分:0)
date_entered