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

时间:2013-10-12 19:54:10

标签: 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   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/

2 个答案:

答案 0 :(得分:3)

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

awk '$1~/c1t1/ {$4="ext2"; sub("c1t1","c1t2",$0)}1' file

解释

  • $1~/c1t1/检查第一个字段是否包含c1t1。如果是,请执行{}
  • $4="ext2"将第4个字段设为“ext2”。
  • sub("c1t1","c1t2",$0)将整个行c1t1中的所有c1t2替换为$0
  • 1打印所有行。

您可以执行它并重定向到另一个文件:awk ... file > new_file

测试

$ awk '$1~/c1t1/ {$4="ext2"; sub("c1t1","c1t2",$0)}1' file

#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/c1t2d0s0 /dev/rdsk/c1t1d0s0 /usr/local ext2 3 yes -

/dev/dsk/c1t2d0s3 /dev/rdsk/c1t1d0s3 /export/user3 ext2 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 -

答案 1 :(得分:1)

您的搜索可能会受益于捕获和替换:

sed -e 's/^\(.*dsk\/\)c1t1\(.*\)ufs\(.*\)$/\1c1t2\2ext2\3/g' some_file

它不具有可读性,还有其他方法可以做到,但\( \)捕获了一些内容。在上面的例子中,我捕获了三件事,当我想将它们转储回来时,我会按照以下方式(按捕获顺序)引用它们:

\1 \2 \3