【问题标题】:How to grep the word next to the search word (....) using Shell script?如何使用 Shell 脚本 grep 搜索词 (....) 旁边的词?
【发布时间】:2016-10-25 19:03:05
【问题描述】:

我编写了一个 shell 脚本来识别给定的单词并 grep 给定单词旁边的单词。请参阅下面的示例输入文件。我还需要在示例输出文件中编写如下所示的相同文件。

#!/bin/bash 

LOGFILE=$1 

if [ -f $LOGFILE ]
then 
        sed -i.bak 's/sqrt(\(\w*\))/sqrt(\1) print(\1)/g' $LOGFILE
else 
        echo "$LOGFILE not found " 
fi

但是当我运行这个 shell 脚本时,我的文件中没有任何反应。请你帮助我好吗?

示例输入文件:

wewe **sqrt(a+B)**  eeenwerer ergv. **sqrt(2x-3)** gtgnwerer ergv. **sqrt(wea*B)** gjjj nwerer ergv. **sqrt(a2/B)** rrnwerer ergv.

预期的文件输出:

wewe **sqrt(a+B)** eeenwerer ergv. ***write (a+B);*** **sqrt(2x-3)** gtgnwerer ergv. ***write (2x-3);*** ** **sqrt(wea*B)** gjjj nwerer ergv. ***write (wea*B);*** ** **sqrt(a2/B)** rrnwerer ergv.***write (a2/B);*** **

【问题讨论】:

  • 您确定输入不会包含sqrt(a+(b*c)/d) 或其他内容,即嵌套括号吗?
  • 嗯,这是我的示例:在 put collisionf2.F90: temp_cons = 4D0*sml_pi/(lambdasqrt(lambda)) collisionf2.F90 : temp_cons = 15*sml_pi/(lambda**sqrt
  • 请使用您的示例输入更新问题。
  • 我用更多示例输入更新问题

标签: shell awk


【解决方案1】:

你可以试试:

awk -f mod.awk input.txt

input.txt 是您输入的日志文件,mod.awk 是:

{
    str=str $0 ORS
}
END {
    str2=""
    prev=""
    while(match(str,/sqrt\(([^)]*)\)/,a)) {
        cur=substr(str,RSTART,RLENGTH)
        end=substr(str,RSTART+RLENGTH)
        str2=str2 substr(str,1,RSTART-1) prev cur
        str=end
        prev="*write(" a[1] ");"
    }
    print str2 str prev
}

给定输入文件input.txt

wewe sqrt(a+B)  eeenwerer ergv. sqrt(2x-3) gtgnwerer ergv. sqrt(wea*B) gjjj nwerer ergv. sqrt(a2/B) rrnwerer ergv.

运行awk -f mod.awk input.txt 给出输出:

wewe sqrt(a+B)  eeenwerer ergv. *write(a+B);sqrt(2x-3) gtgnwerer ergv. *write(2x-3);sqrt(wea*B) gjjj nwerer ergv. *write(wea*B);sqrt(a2/B) rrnwerer ergv.*write(a2/B);

【讨论】:

  • 我得到 awk: my.awk:9: fatal: 1 无效,因为 substr 的参数数量我正在尝试读取文件。请你帮助我好吗。我使用您在此处提供的相同代码并将其命名为 my.awk,我想知道 { str=str $0 ORS } 的含义是什么
  • str $0 ORS 是字符串连接,例如str="a" "b" "c" 给出str="abc"ORS 是输出记录分隔符。它的默认值是换行符“\n”
  • 好的 非常感谢。但是为什么会出现 awk: my.awk:9: fatal: 1 is invalid as number of arguments for substr
  • 你能先试试这个简单文件上的代码:hi sqrt(a+B) you sqrt(2x-3) gtg 吗?你得到同样的错误吗?
  • 好的。尝试在 while 行之后添加以下两行:print "RSTART=\""RSTART"\""print "RLENGTH=\""RLENGTH"\"".. 然后告诉我你得到的简单文件的输出是什么..
【解决方案2】:

如果单词在单独的行中,你不能尝试这个,它会搜索单词并打印它旁边的行。

awk '/要搜索的单词:/{getline;print;}'

【讨论】:

    【解决方案3】:

    由于您想在 'sqrt(' 之后查找除 ')' 之外的所有字符 - 您可以使用 '[^)]*' 来匹配此字符集。 然后,您可以将模式 s​​qrt(...) 和 sqrt(...(...)....) 作为两个单独的案例显式搜索。

    sed '
        s/sqrt(\([^)]*)\)/sqrt(\1) print(\1)/g
        s/sqrt(\([^)]*([^)]*)[^)]*)\)/sqrt(\1) print(\1)/g
    '
    

    如果你把'[^)]*'改成Z就更容易理解了

    sed '
        s/sqrt(\(Z)\)/sqrt(\1) print(\1)/g
        s/sqrt(\(Z(Z)Z)\)/sqrt(\1) print(\1)/g
    '
    

    【讨论】:

      【解决方案4】:

      这有点类似于 Håkon Hægland 的解决方案,但更短,并且也适用于 awk 的旧版本,其中 match() 不能有 3 个参数:

      awk -F'sqrt\\(' '
          { for (i=1; ++i<=NF; )
              $i = gensub("(.*)\\)(.*)", "sqrt(\\1)\\2 write(\\1);", 1, $i)
            print
          }           ' $LOGFILE
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-26
        • 1970-01-01
        • 2020-11-06
        • 1970-01-01
        • 2021-05-21
        • 2015-01-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多