Sed脚本,该脚本将在一行中找到匹配项,并更改该行的另一部分

Sed脚本,该脚本将在一行中找到匹配项,并更改该行的另一部分,sed,backreference,Sed,Backreference,我试图将包含c1t1的行的“FS”类型从ufs更改为ext2,并将这些行上的所有地方的c1t1更改为c1t2。这是文件的外观: #device device mount FS fsck mount mount #to mount to fsck point type pass at boot options # #/dev/dsk/c1d0s2 /dev/rdsk/c1d0s2 /usr ufs 1 y

我试图将包含c1t1的行的“FS”类型从ufs更改为ext2,并将这些行上的所有地方的c1t1更改为c1t2。这是文件的外观:

#device     device      mount       FS  fsck    mount   mount
#to mount   to fsck     point       type    pass    at boot options
#

#/dev/dsk/c1d0s2 /dev/rdsk/c1d0s2 /usr      ufs 1   yes -

fd  -   /dev/fd fd  -   no  -
/proc   -   /proc   proc    -   no  -
/dev/dsk/c0t0d0s1   -   -   swap    -   no  -
/dev/dsk/c0t0d0s0   /dev/rdsk/c0t0d0s0  /   ufs 1   no  -
/dev/dsk/c0t0d0s6   /dev/rdsk/c0t0d0s6  /usr    ufs 1   no  -
/dev/dsk/c0t0d0s4   /dev/rdsk/c0t0d0s4  /var    ufs 1   no  -
/dev/dsk/c0t0d0s5   /dev/rdsk/c0t0d0s5  /local  ufs 2   yes -
/dev/dsk/c0t0d0s3   /dev/rdsk/c0t0d0s3  /usr/openwin    ufs 2   yes -

/dev/dsk/c1t0d0s0   /dev/rdsk/c1t0d0s0  /opt    ufs 3   yes -
/dev/dsk/c1t0d0s3   /dev/rdsk/c1t0d0s3  /export/user1   ufs 3   yes nosuid
/dev/dsk/c1t1d0s0   /dev/rdsk/c1t1d0s0  /usr/local  ufs 3   yes -

/dev/dsk/c1t1d0s3   /dev/rdsk/c1t1d0s3  /export/user3   ufs 3   yes nosuid  
/dev/dsk/c2t0d0s0   /dev/rdsk/c2t0d0s0  /export/home    ufs 4   yes nosuid  
/dev/dsk/c2t0d0s3   /dev/rdsk/c2t0d0s3  /casa6  ufs 4   yes -
/dev/dsk/c2t3d0s0   /dev/rdsk/c2t3d0s0  /export/user2   ufs 5   yes nosuid  
/dev/dsk/c2t3d0s3   /dev/rdsk/c2t3d0s3  /stage  ufs 5   yes -

# ringer.cs.utsa.edu:/usr/local/news    -   /usr/local/news nfs -   yes retry=10    
ringer.cs.utsa.edu:/var/mail    -   /var/mail   nfs -   yes retry=10,actimeo=0  
#ringer.cs.utsa.edu:/var/spool/news -   /var/spool/news nfs -   yes retry=10
#ringer.cs.utsa.edu:/answerbook -   /answerbook nfs -   yes retry=10

swap    -   /tmp    tmpfs   -   yes -
这就是我所能想到的:

s/(^\/dev\/dsk\/c1t1.*)ufs(.*$)/$1ext2$2/

当语法有点混乱时,有时是时候使用
awk

awk '$1~/c1t1/ {$4="ext2"; sub("c1t1","c1t2",$0)}1' file
解释
  • $1~/c1t1/
    检查第一个字段是否包含
    c1t1
    。如果是,则执行
    {}
  • $4=“ext2”
    将第四个字段设置为“ext2”
  • sub(“c1t1”、“c1t2”和$0)
    将整行的所有
    c1t1
    替换为
    c1t2
    $0
  • 1
    打印所有行
您可以执行它并重定向到另一个文件:
awk。。。文件>新建文件

试验
当语法有点混乱时,有时是时候使用
awk

awk '$1~/c1t1/ {$4="ext2"; sub("c1t1","c1t2",$0)}1' file
解释
  • $1~/c1t1/
    检查第一个字段是否包含
    c1t1
    。如果是,则执行
    {}
  • $4=“ext2”
    将第四个字段设置为“ext2”
  • sub(“c1t1”、“c1t2”和$0)
    将整行的所有
    c1t1
    替换为
    c1t2
    $0
  • 1
    打印所有行
您可以执行它并重定向到另一个文件:
awk。。。文件>新建文件

试验
看起来您的搜索可能会从捕获和替换中受益:

sed -e 's/^\(.*dsk\/\)c1t1\(.*\)ufs\(.*\)$/\1c1t2\2ext2\3/g' some_file
它不是那么可读,还有其他的方法,但是
\(\)
捕获了一些东西。在上面的示例中,我捕获了三件事情,当我想将它们重新放入时,我会按以下方式引用它们(按捕获顺序):


看起来您的搜索可能会从捕获和替换中受益:

sed -e 's/^\(.*dsk\/\)c1t1\(.*\)ufs\(.*\)$/\1c1t2\2ext2\3/g' some_file
它不是那么可读,还有其他的方法,但是
\(\)
捕获了一些东西。在上面的示例中,我捕获了三件事情,当我想将它们重新放入时,我会按以下方式引用它们(按捕获顺序):



啊,谢谢你,我被后面的引用弄糊涂了。现在说得通了。这真的很让人困惑,因为
\1
正好被传递到后面的文本或空格(或我们捕获的任何内容)旁边。结果通常很难阅读。是的,当大量的斜杠、反斜杠和所有的东西都在里面时,它会变得非常糟糕。如果你使用
sed-r
,你可以用简单的
(…)
而不是
\(…)
来捕捉组,谢谢你的工作,我被反向引用弄糊涂了。现在说得通了。这真的很让人困惑,因为
\1
正好被传递到后面的文本或空格(或我们捕获的任何内容)旁边。结果往往很难阅读。是的,当大量的斜杠、反斜杠和所有这些都出现在那里时,它会变得非常糟糕。如果你使用
sed-r
,你可以用简单的
(…)
而不是
(…)
,而不是
(…)
,来捕捉群组,他说想要改变每一个
c1t1
。最好是全局
sub()
,也不要将比较限制在第一个字段。@Birei mmmm from
并将这些行上的所有地方的c1t1更改为c1t2
我知道它只指与第一个条件匹配的行。我看不出有什么区别。那好吧。不同的解释。没问题,不是很清楚。从被接受的答案中,我看到是这样的。好的,我看到@MarcusLorenzana。我建议您在使用斜杠处理字符串时使用其他字段分隔符(
sed的#one#two#g
sed的/one/two/g
)相同。这将有助于理解什么是字符串,什么是sed部分。最好是全局
sub()
,也不要将比较限制在第一个字段。@Birei mmmm from
并将这些行上的所有地方的c1t1更改为c1t2
我知道它只指与第一个条件匹配的行。我看不出有什么区别。那好吧。不同的解释。没问题,不是很清楚。从被接受的答案中,我看到是这样的。好的,我看到@MarcusLorenzana。我建议您在使用斜杠处理字符串时使用其他字段分隔符(
sed的#one#two#g
sed的/one/two/g
)相同。它将有助于理解什么是字符串,什么是
sed
部分。