使用命令将字符串添加到文件

使用命令将字符串添加到文件

我需要补充一点:

user_xattr,acl,barrier=1

到我的 /etc/fstab 文件。有没有办法通过 shell 脚本来做到这一点?

我只想编辑“ /”坐骑。

这是我手动编辑之前的内容:

UUID=eb287d10-60a8-4a9a-9148-5f907fc7a8be / ext4 errors=remount-ro 0 1

这是我手动添加行之后的样子:

UUID=eb287d10-60a8-4a9a-9148-5f907fc7a8be / ext4 user_xattr,acl,barrier=1,errors=remount-ro 0 1

我知道该sed -i命令在这里不起作用因为它只添加行......

脚本还可以在多台计算机上运行,​​因此它必须能够“知道” UUID 会有所不同。

答案1

实际上,sed可以很好地工作,但这里还有一些其他选择:

1. sed

sudo sed -i.old -r '/[ \t]\/[ \t]/{s/(ext4[\t ]*)([^\t ]*)/\1\2,user_xattr,acl,barrier=1/}' /etc/fstab

解释:

  • -i.old:就地编辑文件,并创建fstab.old更改之前原始文件的备份。
  • -r:启用扩展正则表达式。
  • /[ \t]\/[ \t]/{}/:如果此行与空格或制表符包围的匹配(如果此行描述了/挂载点)。
  • s/(ext4[\t ]*)([^\t ]*)/\1\2,user_xattr,acl,barrier=1/:s/pat/replacement/是替换运算符,它将替换patreplacement。在这里,我们匹配ext4任何后面的空格或制表符(需要固定匹配,如果您的文件系统不是 ext4,则需要更改它),然后捕获(括号的作用是)其后最长的非空白字符。换句话说,捕获 fstab 的选项字段。然后我们用\1(第一个捕获的模式)、\2(第三个捕获模式,原始选项)以及您想要添加的额外选项替换它们。

2. Perl

sudo perl -i.old -pane 's/$F[3]/$F[3],user_xattr,acl,barrier=1/ if $F[1] eq "/"' /etc/fstab

解释:

  • -i.old:同样,这将导致文件在原地被编辑,并且fstab.old会创建一个名为的备份。
  • -pane-p表示打印每一行,-a自动将输入行按空白处拆分为字段并保存为数组@F-n表示逐行读取并-e允许您在命令行上传递脚本。
  • 仅当第二个 ffield(,挂载点)为时,实际脚本才会将额外选项添加到第 4 个字段的当前值($F[3],第一个字段为) 。$F[0]$F[1]/

3. awk

sudo cp /etc/fstab /etc/fstab.old && 
 awk '($2=="/"){$4=$4",user_xattr,acl,barrier=1"}1;' /etc/fstab.old | sudo tee /etc/fstab

解释:

大多数版本的awk不允许现场编辑,因此第一个命令将创建备份副本。awk然后,将检查第二个字段是否为/,如果是,将向第四个字段(选项)添加所需的文本。1;是 awk 中“打印行”的简写。sudo tee只是一个允许打印的技巧,/etc/fstab因为简单的重定向不适用于sudo

4. 纯 bash

sudo cp /etc/fstab /etc.fstab.old
while read fs mp ty op du pa; do 
    [[ $mp = "/" ]] && op="user_xattr,acl,barrier=1,""$op"; 
    printf "%s %s %s %s %s %s\n" "$fs" "$mp" "$ty" "$op" "$du" "$pa"; 
done < /etc/fstab.old | sudo tee /etc/fstab

解释

  • while read fs mp ty op du pa; do ...; done < /etc/fstab:读取每个 fstab 行并拆分成相关字段。
  • [[ $mp = "/" ]] && op="user_xattr,acl,barrier=1,""$op";如果挂载点是/,则将额外选项添加到$op
  • 只是printf正确打印每一行。

答案2

sed -i未使用仅有的按照您说的添加行。它可以在许多其他情况下使用。在您的例子中,如下所示:

str="/[[:space:]]*ext4[[:space:]]*errors=remount-ro[[:space:]]*0[[:space:]]*1"
sed -i.bak "s#$str#/ ext4 user_xattr,acl,barrier=1,errors=remount-ro 0 1#" /etc/fstab

像这样$str,与类似的东西相同/ ext4 errors=remount-r 0 1(其中每个空格可以是任意一组空格<tab>和),将在文件中 <space>被替换。/ ext4 user_xattr,acl,barrier=1,errors=remount-ro 0 1/etc/fstab

该类[:space:](与空格字符<tab>和匹配<space>)是由 POSIX 指定,因此在任何 shell 中使用它都不会有问题。

相关内容