sed使用日记2020-12-09

作者: 土雕艺术家 | 来源:发表于2020-12-09 16:46 被阅读0次

    一些软件的设置采用配置文档作为读取参数设置的方式,比如SOAPdenovo2、novoplasty。那么每次往里面手动写入信息就比较麻烦。
    所以使用下面这个命令就很方便了:

    #匹配内容后面添加内容
    sed -i   's/匹配内容/&添加内容/' 文件名
    #匹配内容前面添加内容
    sed -i   's/匹配内容/添加内容&/' 文件名
    
    

    可是我们一般使用的/在这里却不是这么方便了,因为我们指引fq1&2的时候难免会带着路径名。
    这么多/的时候就会有冲突了

    sed -i 's/q1=/&/home/Documents/fq1/' config.txt
    
    sed: -e expression #1, char 13: unknown option to `s'
    

    所以我们需要替换分隔符,我知道可以使用 ! 还有 | 和 # 替代 /

    animal1@animalia:~/Documents/20201209_sed_i$ sed -i 's!q1=!&'$fq1'!' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=/home/Documents/fq1
    animal1@animalia:~/Documents/20201209_sed_i$ sed -i 's#q1=#&'$fq1'#' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=/home/Documents/fq1
    animal1@animalia:~/Documents/20201209_sed_i$ sed -i 's|q1=|&'$fq1'|' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=/home/Documents/fq1
    

    而且我还发现这里面单引号和双引号一些奇奇怪怪的事情:
    我们都知道双引号里面的变量才有作用,单引号里面的变量会当成单纯字符串。而当他们两个嵌套的时候那么就会让里面的那个单引号或者双引号失效当初普通字符串。

    animal1@animalia:~/Documents/20201209_sed_i$ echo ' "$fq1" '
     "$fq1"
    animal1@animalia:~/Documents/20201209_sed_i$ echo " '$fq1' "
     '/home/Documents/fq1'
    

    我之所以会发现是我一开始没有想着替换分割字符,而是尝试用单引号和双引号组合来区分sed -i 里的/和路径里的/,然后就发现了。

    animal1@animalia:~/Documents/20201209_sed_i$ sed -i "s#q1=#&'$fq1'#" config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1='/home/Documents/fq1'
    
    animal1@animalia:~/Documents/20201209_sed_i$ sed -i 's#q1=#&"$fq1"#' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1="$fq1"
    
    animal1@animalia:~/Documents/20201209_sed_i$ sed -i 's#q1=#&$fq1#' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=$fq1
    
    animal1@animalia:~/Documents/20201209_sed_i$ sed -i "s#q1=#&$fq1#" config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=/home/Documents/fq1
    

    几种尝试之下只有最后一种安排是我想要的效果。路径如果加上单引号有些软件还是不能识别的,所以第一种情况也不能要的。
    还有就是下面这种情况。这个尝试本来是想用单引号包围$fq1,很明显系统识别吧第一个和第二单引号作为一对,而不是我想象的第三个和第四个一对。
    但是也完美地完成了任务哈哈。

    animal1@animalia:~/Documents/20201209_sed_i$ sed -i 's!q1=!&'$fq1'!' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=/home/Documents/fq1
    

    这就让我很好奇sed -i读取到的内容是啥样的?
    我想到写成shell然后用-x展示执行过程看看,是咋回事。

    sed.sh:
    ########
    fq1=/home/Documents/fq1
    touch config.txt
    echo q1= > config.txt
    echo $fq1
    sed -i 's!q1=!&'$fq1'!' config.txt
    ########
    animal1@animalia:~/Documents/20201209_sed_i$ bash -x sed.sh
    + fq1=/home/Documents/fq1
    + touch config.txt
    + echo q1=
    + echo /home/Documents/fq1
    /home/Documents/fq1
    + sed -i 's!q1=!&/home/Documents/fq1!' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ l
    config.txt  sed.sh
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=/home/Documents/fq1
    
    
    
    sed.sh:
    ########
    fq1=/home/Documents/fq1
    touch config.txt
    echo q1= > config.txt
    echo $fq1
    sed -i "s!q1=!&$fq1!" config.txt
    ########
    animal1@animalia:~/Documents/20201209_sed_i$  bash -x sed.sh
    + fq1=/home/Documents/fq1
    + touch config.txt
    + echo q1=
    + echo /home/Documents/fq1
    /home/Documents/fq1
    + sed -i 's!q1=!&/home/Documents/fq1!' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=/home/Documents/fq1
    
    sed.sh:
    ########
    fq1=/home/Documents/fq1
    touch config.txt
    echo q1= > config.txt
    echo $fq1
    sed -i "s!q1=!&"$fq1"!" config.txt
    ########
    animal1@animalia:~/Documents/20201209_sed_i$ bash -x sed.sh
    + fq1=/home/Documents/fq1
    + touch config.txt
    + echo q1=
    + echo /home/Documents/fq1
    /home/Documents/fq1
    + sed -i 's!q1=!&/home/Documents/fq1!' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1=/home/Documents/fq1
    
    

    上面这三种情况实际上都是没有嵌套的,但是很明显最后sed -i
    要的内容是单引号内纯字符内容。
    接下来我尝试一下嵌套的结果是啥样。

    sed.sh:
    ########
    fq1=/home/Documents/fq1
    touch config.txt
    echo q1= > config.txt
    echo $fq1
    sed -i "s!q1=!&'$fq1'!" config.txt
    ########
    animal1@animalia:~/Documents/20201209_sed_i$ bash -x sed.sh
    + fq1=/home/Documents/fq1
    + touch config.txt
    + echo q1=
    + echo /home/Documents/fq1
    /home/Documents/fq1
    + sed -i 's!q1=!&'\''/home/Documents/fq1'\''!' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1='/home/Documents/fq1'
    
    animal1@animalia:~/Documents/20201209_sed_i$ echo 's!q1=!&'\''/home/Documents/fq1'\''!'
    s!q1=!&'/home/Documents/fq1'!
    
    
    sed.sh:
    ########
    fq1=/home/Documents/fq1
    touch config.txt
    echo q1= > config.txt
    echo $fq1
    sed -i 's!q1=!&"$fq1"!' config.txt
    ########
    animal1@animalia:~/Documents/20201209_sed_i$ bash -x sed.sh
    + fq1=/home/Documents/fq1
    + touch config.txt
    + echo q1=
    + echo /home/Documents/fq1
    /home/Documents/fq1
    + sed -i 's!q1=!&"$fq1"!' config.txt
    animal1@animalia:~/Documents/20201209_sed_i$ cat config.txt
    q1="$fq1"
    
    
    ************
    #这里面我觉得需要拆解理解一下's!q1=!&'\''/home/Documents/fq1'\''!'的意思
    #这是按照机器的思维进行的分割
    's!q1=!&'    \'     '/home/Documents/fq1'     \'      '!'
    #也就是对单引号进行了转义但是不知为何要对其他部分也都加上单引号?.
    
    #我想象中的分割
    's!q1=!&    ' \' '   /home/Documents/fq1    '\''      !'
    #对单引号进行\转义但是对\加上单引号
    #但是我的思维是不对的,我试了如下命令
    echo '\'
    \
    #这说明如果单引号是给\那么\就失去了转义功能。
    

    感觉这里面弯弯绕还挺多,但是我最后还是觉得
    sed -i 's/匹配内容/&添加内容/' 文件名
    这里面的单引号内容能被单引号分割感觉不爽,但是实际上确实可以的。

    相关文章

      网友评论

        本文标题:sed使用日记2020-12-09

        本文链接:https://www.haomeiwen.com/subject/youhgktx.html