【问题标题】:Shell Script - Search before 'touching' the file. (csh)Shell 脚本 - 在“接触”文件之前进行搜索。 (csh)
【发布时间】:2014-04-24 17:28:50
【问题描述】:

家庭作业 - 不要只是给我一个答案,但我确实被困在这个问题上好几天了。这也解释了为什么我坚持使用 csh,这当然会加剧问题。

shell 脚本需要在文件中搜索字符串并将其替换为新字符串,如果已找到该字符串且文件已被更改,则创建一个备份文件。够简单吧?

这是我的代码。

    #!/bin/csh                                                                     
set currentWord=$1
set newWord=$2
set fileName=$3

#sed -i.bak -e  "s/$1/$2/g" $3                                                  

  if  (grep -q $1 $3)  then
     sed -i.bak -e "s/$1/$2/g" $3
   else
     echo "The string is not found."
   endif

我遇到的问题是它不应该“触摸”文件,除非找到字符串。我一直在这样做的方式以任何一种方式创建文件,有时它们最终只是相同的文件。我也尝试过只使用一个 sed 命令,但我最接近解决方案的方法是将 sed 命令放入 if then else 中。现在我收到“if 表达式语法”错误 - 这让我觉得我根本不能使用 grep,需要重新格式化它或使用其他东西。

【问题讨论】:

    标签: shell unix csh


    【解决方案1】:

    您需要检查grep 的退出状态。有几种方法可以做到这一点。

    你要么:

    调用grep,然后检查特殊变量$status,如

    #!/bin/csh
    
    set currentWord=$1
    set newWord=$2
    set fileName=$3
    
    grep -q $currentWord $fileName
    
    if !($status) then
        sed -i.bak -e "s/$currentWord/$newWord/g" $fileName
    else
        echo "The string is not found."
    endif
    

    或者,由于此处不需要$status 的实际值,因此只需使用更简洁的形式

    #!/bin/csh
    
    set currentWord=$1
    set newWord=$2
    set fileName=$3
    
    if { grep -q $currentWord $fileName } then
        sed -i.bak -e "s/$currentWord/$newWord/g" $fileName
    else
        echo "The string is not found."
    endif
    

    第二个是我最喜欢的。

    【讨论】:

    • 非常感谢,第二个选项很有效。正是我想要完成的事情,只是我一直在做这件事。
    • 您也可以只使用两个管道 - grep -q $currentWord $fileName && sed -i.bak -e "s/$currentWord/$newWord/g" $filename。如果grep 命令指示成功,那只会运行sed 命令...
    • 循环和管道 (@Twalberg) 建议都有效,现在我发现自己又卡住了。有没有一种简单的方法可以通过标准输入接受无限的指定文件?我正在尝试的一切要么只接受第一个文件(调整 sed/grep),要么运行该目录中的每个文件(通配符/正则表达式)。两个小时后,我想我又一次过于复杂了。
    猜你喜欢
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2015-10-13
    • 2014-07-09
    • 2014-08-06
    • 1970-01-01
    • 2010-11-26
    相关资源
    最近更新 更多