awk onliner脚本在目录下搜索2个字符串的文件

时间:2011-04-27 22:22:09

标签: string unix search command-line awk

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

例如,

file1看起来像:

abc
def
str1
ghi
str2

file2看起来像:

abc
str2
def
ghi
str1
pqe

我的搜索应该返回file1。

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

提前致谢。

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

上面的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 one liner

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

答案 2 :(得分:0)

这不是一个单行,但你可以删除换行符,问题就解决了:)

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!