首页 > 解决方案 > 用 sed 替换不能正常工作

问题描述

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

$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

但同样的回声作品?

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

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

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

标签: bashsedcat

解决方案


首先,整个命令可以用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

我们不知道您的意图是什么,但看起来您想将目录名重命名signalsnb-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__
    

注意:永远不要使用catfor 循环文件!


推荐阅读