我正在使用Awk脚本将大文本文档拆分为独立文件。我做到了,现在我正在处理14k文本文件。这里的问题是,很多文件只有三行文本,对我来说保留它们没有用。
我知道我可以使用awk 'NF>=3' file
删除文本中的行,但是我不想删除文件中的行,而是要删除内容仅是两三个文本行的文件。
谢谢。
答案 0 :(得分:3)
请问您可以尝试执行find
命令。(已通过GNU awk
测试)
find /your/path/ -type f -exec awk -v lines=3 'NR>lines{f=1; exit} END{if (!f) print FILENAME}' {} \;
因此,上面将打印控制台上少于3行的文件名。对结果感到满意后,请尝试以下操作将其删除。只有在您对上面命令的输出满意之后,甚至 我才建议您先在测试目录中运行以下命令,一旦您完全满意,然后再执行以下命令。 (从下面删除echo
还是为了安全起见:))
find /your/path/ -type f -exec awk -v lines=3 'NR>lines{f=1; exit} END{exit !f}' {} \; -exec echo rm -f {} \;
答案 1 :(得分:2)
如果当前目录下的文件都是文本文件,这应该是高效的和便携式:
for f in *; do
[ $(head -4 "$f" | wc -l) -lt 4 ] && echo "$f"
done # | xargs rm
检查列表,如果看起来不错,则删除最后一行上的#
以实际上删除不需要的文件。
为什么使用head -4
?由于wc
不知道什么时候退出。假设一半的文本文件的长度都超过TB。如果仅是wc -l
的话,那就太慢了。
答案 2 :(得分:1)
您可以使用wc
计算行数,然后决定是否删除文件。您应该编写一个Shell脚本而不是仅仅使用awk
命令。
答案 3 :(得分:1)
您可以尝试Perl。如果行数> 3
,将关闭文件句柄ARGV,下面的解决方案将非常有效 perl -nle ' close(ARGV) if ($.>3) ; $kv{$ARGV}++; END { for(sort keys %kv) { print if $kv{$_}>3 } } ' *
如果您希望通过管道传输其他命令(例如find)的输出,则可以像这样使用它
$ find . -name "*" -type f -exec perl -nle ' close(ARGV) if ($.>3) ; $kv{$ARGV}++; END { for(sort keys %kv) { print if $kv{$_}>3 } } ' {} \;
./bing.fasta
./chris_smith.txt
./dawn.txt
./drcatfish.txt
./foo.yaml
./ip.txt
./join_tab.pl
./manoj1.txt
./manoj2.txt
./moose.txt
./query_ip.txt
./scottc.txt
./seats.ksh
./tane.txt
./test_input_so.txt
./ya801.txt
$
wc -l *在同一目录中的输出
$ wc -l *
12 bing.fasta
16 chris_smith.txt
8 dawn.txt
9 drcatfish.txt
3 fileA
3 fileB
13 foo.yaml
3 hubbs.txt
8 ip.txt
19 join_tab.pl
6 manoj1.txt
6 manoj2.txt
5 moose.txt
17 query_ip.txt
3 rororo.txt
5 scottc.txt
22 seats.ksh
1 steveman.txt
4 tane.txt
13 test_input_so.txt
24 ya801.txt
200 total
$