【问题标题】:replacement with sed does not work correctly用 sed 替换不能正常工作
【发布时间】:2018-09-27 07:57:16
【问题描述】:

我尝试了以下命令并解释了我的问题:

$cat __sphlist__
signals/APASCI/algi0/algi0.sph
signals/APASCI/ancl0.sph
signals/APASCI/anpe0.sph
signals/APASCI/cepe0.sph

为什么下面的命令不起作用,并显示信号的内容! :

$cat __sphlist__ | while read f; do sed 's/signals/nb-signals/'  $f; done

但是 echo 也一样?

$cat __sphlist__ | while read f; do echo  $f; done

我像下面这样更改了 sed 命令并且它可以工作,我想知道有什么区别?

$cat __sphlist__ | sed 's/signals/nb-signals/' | while read f; do echo $f ; done

【问题讨论】:

    标签: bash sed cat


    【解决方案1】:

    您应该使 sed 在文件 sphlist 上工作,而不是该文件中的行作为输入。所以:

    sed 's/signals/nb-&/' sphlist 
    

    应该这样做。

    如果要更改文件内容,添加-i(gnu sed)

    【讨论】:

      【解决方案2】:

      首先,可以将整个命令替换为Kent的解决方案。

      现在回答你的问题:

      为什么下面的命令不起作用,并显示信号的内容!

      cat __sphlist__ | while read f; do sed 's/signals/nb-signals/'  $f; done
      

      这不是的问题,而是你对的理解。

      期望接收文件名作为输入,并将对该文件执行所有操作。这意味着如果变量f 有一个与文件名匹配的字符串(第一行等于signals/APASCI/algi0/algi0.sph), 将在该文件上执行其替换并因此打印其内容。如果$f 不匹配某个文件,则会失败。

      你写的命令相当于:

      sed 's/signals/nb-signals/' signals/APASCI/algi0/algi0.sph
      sed 's/signals/nb-signals/' signals/APASCI/ancl0.sph
      sed 's/signals/nb-signals/' signals/APASCI/anpe0.sph
      sed 's/signals/nb-signals/' signals/APASCI/cepe0.sph
      

      我们不知道您的意图是什么,但您似乎想将目录名称 signals 重命名为 nb-signals。以下是修正脚本的几种方法:

      • 在管道中使用echo,让/dev/stdin中读取

          while read -r f; do echo "$f" | sed 's/signals/nb-signals/'; done < __sphlist__
        
      • 使用 here-string 作为 的输入

          while read -r f; do sed 's/signals/nb-signals/' <<< "$f"; done < __sphlist__   
        
      • 使用 bash 替换

          while read -r f; do echo "${f/signals/nb-signals}"; done < __sphlist__ 
        
      • 只需使用

          sed 's/signals/nb-signals/' __sphlist__
        

      注意:切勿使用cat 循环文件!

      【讨论】:

        【解决方案3】:

        How SED works.

        SED 可以逐一处理文件中的所有行,因此您不必为 SED 的每一行添加 WHILE。

        $cat sphlist | while read f; do sed 's/signals/nb-signals/' $f; done
        

        在上面,SED 将 $f 视为一个文件。由于没有这样的文件,您会收到“没有这样的文件或目录”错误。

        $cat sphlist | while read f; do echo $f; done
        

        上面的命令没有什么特别之处,因为您是逐行阅读并打印它们。

        $cat sphlist | sed 's/signals/nb-signals/' | while read f; do echo $f ; done
        

        在上面你将 CAT 结果传递给 SED,你可以像下面这样直接做

        sed 's/signals/nb-signals/' sphlist 
        

        然后您将 SED 的结果传递给 WHILE,它会逐行打印。以上只是您所需要的。

        sed 's/signals/nb-signals/g' sphlist 
        

        注意到上面命令中 SED 的最后一个 'g' 了吗?这是为了全局替换文件中的值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-06
          • 1970-01-01
          • 1970-01-01
          • 2014-01-04
          • 1970-01-01
          • 2013-03-30
          相关资源
          最近更新 更多