我一直在尝试编写一个Grep表达式,它将遍历一个目录中的所有文本文件,并且只返回包含我正在查找的所有模式的文件。示例输入文件如下所示:
A 29 LIJ uniteresting_numbers uniteresting_numbers uniteresting_numbers
A 30 RTX uniteresting_numbers uniteresting_numbers uniteresting_numbers <=B
A 31 BRN uniteresting_numbers uniteresting_numbers uniteresting_numbers <=B
A 32 SJY uniteresting_numbers uniteresting_numbers uniteresting_numbers <=B
A 33 MRT uniteresting_numbers uniteresting_numbers uniteresting_numbers
A 34 MUY uniteresting_numbers uniteresting_numbers uniteresting_numbers
A 35 OOP uniteresting_numbers uniteresting_numbers uniteresting_numbers
我希望能够搜索我的目录中的所有.txt文件,并且只返回包含以下所有的文件:
A 30 RTX uniteresting_numbers uniteresting_numbers uniteresting_numbers <=B
A 31 BRN uniteresting_numbers uniteresting_numbers uniteresting_numbers <=B
A 32 SJY uniteresting_numbers uniteresting_numbers uniteresting_numbers <=B
如果这三个文件中的任何一个都不存在,我希望跳过该文件。我将知道在每种情况下我正在寻找的是什么两位数字和三个字母的代码。我想输入这些变量作为用户输入的变量。我正在寻找的是文件,其中我所有的两位数字和感兴趣的三个字母代码在最后都有一个<=B。
Here is the code I have thus far:
echo What do you want to name your output file?
read myoutput
for file in *.txt; do
if grep -q "RTX$(printf '\t')*[0-9]$(printf '\t')*[0-9]$(printf '\t')*[0-9]" <"$file"; then
if grep -q "BRN$(printf '\t')*[0-9]$(printf '\t')*[0-9]$(printf '\t')*[0-9]" <"$file"" <"$file"; then
if grep -q "SJY$(printf '\t')*[0-9]$(printf '\t')*[0-9]$(printf '\t')*[0-9]" <"$file"" <"$file"; then
echo "$file" >>"$myoutput".txt
else
echo not found
fi
fi
fi
done
注意,我没有添加用户输入三个字母代码和两位数字的部分。这不应该是terrible.In输入数据,有一个制表符分隔每一列。因为我现在有它,我可以搜索所有的方式,直到最后的标签和<=B。
我试过了,但没有任何运气:
echo What do you want to name your output file?
read myoutput
for file in *.txt; do
if grep -q "RTX$(printf '\t')*[0-9]$(printf '\t')*[0-9]$(printf '\t')*[0-9]$(printf '\t')$(printf '<=B')" <"$file"; then
if grep -q "BRN$(printf '\t')*[0-9]$(printf '\t')*[0-9]$(printf '\t')*[0-9]$(printf '\t')$(printf '<=B')" <"$file"" <"$file"; then
if grep -q "SJY$(printf '\t')*[0-9]$(printf '\t')*[0-9]$(printf '\t')*[0-9]*$(printf '\t')$(printf '<=B')*" <"$file"" <"$file"; then
echo "$file" >>"$myoutput".txt
else
echo not found
fi
fi
fi
done
任何帮助都是非常感谢的。在某些情况下,我将有三个以上的<=B行我正在寻找。有没有一种简单的方法可以修改它来查找n个<=B行?非常感谢大家!
编辑:我按照建议移动到了awk
要使用awk执行此操作,我输入了以下内容:
#!/bin/bash
echo What do you want to name your output file?
read myoutput
for file in *.txt; do
if awk '/30/ && /RTX/ && /B/' "$file"; then
echo it worked
fi
done
“它成功了”这句话出现了6次。在我测试这个脚本的迷你目录中有6个文件。实际上,这些文件中只有3个与awk模式匹配。如何让"then“后面的代码只在包含awk模式的文件上执行?基于这里的教程,我尝试了以下方法:https://www.thegeekstuff.com/2010/02/awk-conditional-statements
#!/bin/bash
echo What do you want to name your output file?
read myoutput
for file in *.txt; do
$ awk '{
if ($2 =="30" || $3 == "RTX" || $7 == "B")
echo it worked
}' "$file"
done
我没有成功。感谢您的指导!
发布于 2019-04-10 09:25:45
尽管它可能与您的方法不同,但请尝试以下方法:
myoutput="myoutput.txt"
for f in *.txt; do
awk -v output="$myoutput" -v numbers="30 31 32" -v strings="RTX BRN SJY" '
BEGIN {
split(numbers, num)
split(strings, str)
delete matched
}
{
for (n in num) {
if (match($0, "^A\t" num[n] "\t" str[n] "\t[0-9]+\t[0-9]+\t[0-9]+\t<=B$")) {
matched[n]++
}
}
}
END {
for (n in num) {
if (!matched[n]) {
exit
}
}
print FILENAME >> output
} ' "$f"
done
您可以将外壳变量numbers
和strings
赋给用户想要的任意长度。
https://stackoverflow.com/questions/55600226
复制相似问题