我正在学习grep命令。我想做一个程序,当用户输入多个单词时,输出一个包含数据文件中单词的行。因此,我将用户输入的单词连接起来,并将它们放在grep命令中,以创建我想要的程序。但这是手术室。我想做手术。
因此,我学习了如何使用和操作grep命令,如下所示。
cat <file> | grep 'pattern1' | grep 'pattern2' | grep 'pattern3'但我不知道如何将用户输入放在“pattern1”、“pattern2”、“pattern3”位置。因为未确定用户输入的字数。随着用户输入的增加,必须使用越来越多的管道来执行grep,但是我不知道如何构建这个部分。
用户输入如下:
$ [the name of my program] 'pattern1' 'pattern2' 'pattern3' ...我真的很感谢你的帮助。
发布于 2022-03-18 13:00:26
建议使用awk模式逻辑:
awk '/RegExp-pattern-1/ && /RegExp-pattern-2/ && /RegExp-pattern-3/ 1' input.txt优点:您可以在&&模式上使用逻辑运算符||。你只扫描了一次整个文件。
缺点:必须提供文件列表(不能遍历子目录),与grep -E或grep -P相比,grep -P语法有限
发布于 2022-03-19 14:06:28
使用grep -f,当每个条目都位于文件中的一行时,可以实现grep多个项。
使用<(command),您可以让Bash认为command的结果是一个文件。
使用printf "%s\n"和参数列表,每个参数都打印在新行上。
合起来:
grep -f <(printf "%s\n" "$@") datafile发布于 2022-03-18 06:52:16
原则上,您所要求的可以通过一个循环来完成,该循环将输出到一个临时文件。
file=inputfile
temp=$(mktemp -d -t multigrep.XXXXXXXXX) || exit
trap 'rm -rf "$temp"' ERR EXIT
for regex in "$@"; do
grep "$regex" "$file" >"$temp"/output
mv "$temp"/output "$temp"/input
file="$temp"/input
done
cat "$temp"/input然而,更好的解决方案可能是安排Awk一次检查所有模式,避免反复阅读相同的行。
用完整的引文将参数传递给Awk并不是一件简单的事。在这里,我们只需将它们作为命令行参数传递,并将它们处理到Awk脚本本身的数组中。
awk 'BEGIN { for(i=1; i<ARGC; ++i) a[i]=ARGV[i];
ARGV[1]="-"; ARGC=1 }
{ for(n=1; n<=i; ++n) if ($0 !~ a[n]) next; }1' "$@" <file简单地说,在BEGIN块中,我们将命令行参数从ARGV复制到a,然后替换ARGV和ARGC来传递Awk --一个新的(表见的)命令行参数数组,其中只有-,这意味着读取标准输入。然后,我们简单地遍历a,如果标准输入中的当前输入行不匹配,则跳到下一行。任何剩余的行都与我们传入的所有模式相匹配,因此被打印出来。
https://stackoverflow.com/questions/71523095
复制相似问题