我有一个包含33.869行的文本文件,我必须过滤30.067行。
举个例子:
文件: input.txt (csv与33.869行一样)
#00001:A123456.10.101.102,first,row,value2,1
#00002:A123456.10.101.103,second,row,value7,85
(omissis)
#33869:A123456.25.170.180,last,test,value9,0
文件: filter.txt (由“\ n”以30.067行分隔的值列表)
A123456.10.101.102
A123456.10.101.103
(omissis)
A123456.24.150.115
(预期)输出文件: output.txt (csv喜欢从input.txt获取30.067行):
#00001:A123456.10.101.102,first,row,value2,1
#00002:A123456.10.101.103,second,row,value7,85
(omissis)
#30067:A123456.24.150.115,whatever,x,y,99
我正在使用的命令是:
#!/bin/bash
/bin/grep --file="filter.txt" input.txt > output.txt
但返回的错误是
/bin/grep: Argument list too long
我是否被迫在较小的块中拆分“filter.txt”?
允许的限制是什么?
我没有找到man code
命令的限制。
答案 0 :(得分:3)
如果输入文件中没有正则表达式,则应切换到可以读取大量输入记录的grep -F
。
如果不这样做,拆分输入文件比在同一个文件上运行30,000多次grep
次迭代效率要高得多。
这里分成10,000行的块;适应不同的因素应该是微不足道的。
#!/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
答案 1 :(得分:2)
根据你所写的内容,我想知道grep
是否适合这项工作。使用grep
,您通常会尝试应用一小组匹配规则,表示为正则表达式。在您的情况下,您匹配一长串文字。
这似乎是找到full_file.txt
和filtered.txt
共有的行的情况。您可能希望查看以下工具来实现此目的:
join
(http://linux.die.net/man/1/join)为您提供两个文件共有的行。请注意,必须对这两个文件进行排序。您可以使用流程替换来实现此目的。combine
(http://linux.die.net/man/1/combine)是一个更通用的实用程序,不需要对输入进行排序。但它可能无处不在。答案 2 :(得分:1)
如何在文件的每一行上进行迭代?类似的东西:
while IFS= read -r i ; do
grep "$i" full_file.txt
done < grep_filter.txt >filtered.txt
答案 3 :(得分:1)
使用awk
:
awk -F"[:,]" 'FNR==NR{a[$2]=$0;next} ($0 in a) {print a[$0]}' input.txt filter.txt