【问题标题】:awk onliner script to search files under a dir for 2 stringsawk onliner 脚本在目录下搜索文件以查找 2 个字符串
【发布时间】:2011-08-14 06:11:12
【问题描述】:

我需要搜索字符串 str1 出现在字符串 str2 之前的文件。两个字符串都在单独的行中。

例如, file1 看起来像:

abc
def
str1
ghi
str2

file2 看起来像:

abc
str2
def
ghi
str1
pqe

我的搜索应该返回 file1。

它应该是我可以在 unix 的命令行上运行的单行脚本。

提前致谢。

【问题讨论】:

    标签: string unix search command-line awk


    【解决方案1】:

    所以,这是你的awk 一个班轮

    awk -vRS="\0777" '/str1.*str2/{print FILENAME}' file*
    

    【讨论】:

    • @ghostdog...这是否意味着RS="\0777" 记录分隔符是换行符?这究竟是做什么的?
    • 这意味着将整个文件吞入(作为一个完整的字符串)。所以在 str2 之前找到 str1 会打印文件名
    • +1 来自我。这是我学到的新东西。谢谢 ghostdog
    • @zombie,没问题。实际上RS="\0" 也应该做同样的事情。
    【解决方案2】:

    上面的 Sed 1 衬里:

    F="file1" && test ! -z $(sed -n '/str1/,/str2/{/^str2$/p;}' "$F") && echo "$F"
    
    F="file2" && test ! -z $(sed -n '/str1/,/str2/{/^str2$/p;}' "$F") && echo "$F"
    

    输出

    file1
    

    这里是 awk 一个班轮

    F="file1" && awk '{if ($0 == "str1") {a=NR} else if ($0 == "str2" && a> 0 && a<NR) {print FILENAME} }' $F
    
    F="file2" && awk '{if ($0 == "str1") {a=NR} else if ($0 == "str2" && a> 0 && a<NR) {print FILENAME} }' $F
    

    输出

    file1
    

    【讨论】:

    • 您可以使用FILENAME 而不是将$F 作为变量传递给awk
    • 非常感谢,我不知道FILENAME
    【解决方案3】:

    这不完全是单行,但您可以删除换行符,问题就解决了:)

    for file in $(ls) ; do
      awk "/str1/{found=1}/str2/{if(found) print \"$file\"}" $file
    done
    

    它的作用:对于ls列出的每个文件,如果str1出现在其中,脚本将其标记在变量found中:

    /str1/{found=1}
    

    然后,当str2 出现在一行中时,它会验证是否设置了found。如果是,打印文件名:

    /str2/{
        if (found) 
            print "$file"
    }
    

    编辑:还有更简洁的方法可以解决您的问题,使用findxargs

    find . -print0 -maxdepth 1 | \
        xargs -0 -I{} awk '/str1/{found=1}/str2/{if(found) print "{}"}' "{}"
    

    它也更安全,因为它处理名称中带有空格的文件。此外,您可以将其扩展为在子目录中搜索,只需删除 -maxdepth 1 选项。请注意,awk 脚本未更改。

    (使用findxargs 总是有一个很好的解决方案,但是这个解决方案总是有点难找到:D)

    HTH!

    【讨论】:

    • 无用的ls。使用 shell 扩展
    • @ghostdog74 你是对的。幸运的是,第二种解决方案也已经解决了这个问题。
    • @brandizzi:第二种方法发现文件 eveif str2 在 str1 之前。这不是它应该做的。顺便说一句,在第一个解决方案中,我如何查看当前目录下的所有目录,而不是当前目录中的“ls”?
    • 我正在尝试查找。 -print0 | xargs -0 -I{} awk '/str1/{found=1}/str2/{if(found) print "{}"}' "{}" 但是如果 str2 在 str1 之前,它会返回文件名。
    • @hari: 你的意思是only 在下面的目录中搜索还是also 在下面的目录中搜索?如果是第二种情况,只需将$(ls) 替换为$(find .) 如果您只想查看确切 一个目录下的文件,请将$(ls) 替换为$(find . -depth 2);如果要在下面的 all 目录中查找文件,请使用 $(find . -mindepth 2)find 是一个很棒的工具,我想说:)
    猜你喜欢
    • 2021-10-18
    • 2014-12-19
    • 1970-01-01
    • 2018-05-05
    • 2020-04-07
    • 2012-05-11
    • 2015-07-06
    • 2011-01-20
    • 2010-12-03
    相关资源
    最近更新 更多