bash/bin/grep:参数列表太长(使用--file选项)
我有一个包含33.869行的文本文件,我必须过滤其中的30.067行 举个例子: 文件:input.txt(类似csv的33.869行) 文件:filter.txt(以“\n”分隔的值列表,共30.067行) (预期)输出文件:Output.txt(类似于csv,其中30.067行取自input.txt): 我使用的命令是:bash/bin/grep:参数列表太长(使用--file选项),bash,grep,Bash,Grep,我有一个包含33.869行的文本文件,我必须过滤其中的30.067行 举个例子: 文件:input.txt(类似csv的33.869行) 文件:filter.txt(以“\n”分隔的值列表,共30.067行) (预期)输出文件:Output.txt(类似于csv,其中30.067行取自input.txt): 我使用的命令是: #!/bin/bash /bin/grep --file="filter.txt" input.txt > output.txt 但返回的错误是 /bin/grep
#!/bin/bash
/bin/grep --file="filter.txt" input.txt > output.txt
但返回的错误是
/bin/grep: Argument list too long
我是否被迫将“filter.txt”拆分成更小的块
允许的限额是多少
我没有找到
人工编码
命令的限制。从你写的内容来看,我想知道grep
是否是这项工作的合适工具。使用grep
时,您通常会尝试应用一小组匹配规则,以正则表达式表示。在您的情况下,您需要匹配一长串文字
这似乎是一种查找full_file.txt
和filtered.txt
有共同点的行的情况。您可能需要查看以下工具来实现这一点:
()提供两个文件共有的行。请注意,两个文件都必须进行排序。您可以使用流程替换来实现这一点join
()是一个更通用的实用程序,它不需要对输入进行排序。但它可能并非无处不在combine
while IFS= read -r i ; do
grep "$i" full_file.txt
done < grep_filter.txt >filtered.txt
而IFS=read-ri;做
grep“$i”full_file.txt
完成filter.txt
如果输入文件中没有正则表达式,您应该切换到grep-F
,它可以读取大量的输入记录
如果做不到这一点,拆分输入文件将比在同一个文件上运行30000多次grep
要高效得多
这里是10000行的分块;适应不同的因素应该是微不足道的
#!/bin/sh
t=$(mktemp -d -t fgrepsplit.XXXXXXXXXXXX) || exit
trap 'rm -rf "$t"' EXIT # Remove temp dir when done
trap 'exit 127' HUP INT TERM # Remove temp dir if interrupted, too
split -l 10000 "$1" "$t"/pat
for p in "$t"/pat*; do
grep -F -f "$p" "$2"
done
使用awk
:
awk -F"[:,]" 'FNR==NR{a[$2]=$0;next} ($0 in a) {print a[$0]}' input.txt filter.txt
问题有点不同。让我重命名文件,让我说清楚一点。我需要找到“values.txt”到“input.txt”生成“output.txt”。“values.txt”包含必须搜索内容的子字符串“input.txt”包含一个值列表(以及其他信息)“output.txt”必须包含“input.txt”上的所有可用信息,但经过“values.txt”过滤。“join”命令仅在字段相同时有效。事实并非如此。如果我没有任何其他机会,这是我将采用的独特方法。它会慢得多,但无论如何它满足了我的目的。谢谢你的建议!我在我的解决方案中添加了三重建议太好了!有用!比兰特!我喜欢!
while IFS= read -r i ; do
grep "$i" full_file.txt
done < grep_filter.txt >filtered.txt
#!/bin/sh
t=$(mktemp -d -t fgrepsplit.XXXXXXXXXXXX) || exit
trap 'rm -rf "$t"' EXIT # Remove temp dir when done
trap 'exit 127' HUP INT TERM # Remove temp dir if interrupted, too
split -l 10000 "$1" "$t"/pat
for p in "$t"/pat*; do
grep -F -f "$p" "$2"
done
awk -F"[:,]" 'FNR==NR{a[$2]=$0;next} ($0 in a) {print a[$0]}' input.txt filter.txt