【问题标题】:Remove text files with less than three lines删除少于三行的文本文件
【发布时间】:2019-06-26 23:11:53
【问题描述】:

我正在使用 Awk 脚本将大文本文档拆分为独立的文件。我做到了,现在我正在处理 14k 文本文件。这里的问题是有很多文件只有三行文本,我保留它们没有用。

我知道我可以使用awk 'NF>=3' file 删除文本中的行,但我不想删除文件中的行,而是想删除内容只有两到三个文本行的文件。

提前致谢。

【问题讨论】:

  • 将现有脚本修改为不创建 3 行或更少行的文件不是更有意义吗?
  • 是的,完全是。问题是我在运行脚本时遇到了很多麻烦,我不得不多次修改它以提取我想要的所有文件。这不是最优雅的解决方案,但是哦。无论如何,RavinderSigh 给我的解决方案解决了我所有的问题。

标签: bash text awk


【解决方案1】:

请您尝试关注findcommand。(使用 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 {} \;

【讨论】:

  • END {} 总是被执行,即使脚本被exit 终止。所以打印了所有文件名。无论如何,退出状态有效。
  • @Wiimm,谢谢你告诉我,我现在已经修好了。
  • OP 想要删除具有 3 或更少 行的文件,而不仅仅是少于 3 行。考虑您的第一个脚本。如果 NR 达到 4,则 f 设置为 1,并且脚本退出而不打印 FILENAME。如果 NR 从未达到 4(即它是 3 或更少),则永远不会设置 f,因此脚本会打印 FILENAME。这正是您想要发生的事情,因为您正在尝试生成要删除的文件列表。您的第二个脚本的类似逻辑。
  • @EdMorton,Ed Sir 明白了,谢谢您的精彩解释,祝您周末愉快:)
  • 好的,这个解决方案解决了我所有的问题。它工作得很好!是的,我想删除每个包含 3 行或更少行的文件。我修改了脚本,看看哪一个以令人满意的方式解决了它,瞧,我所有的问题都消失了:D。非常感谢!
【解决方案2】:

如果当前目录下的文件都是文本文件,这样应该是高效可移植的:

for f in *; do 
    [ $(head -4 "$f" | wc -l) -lt 4 ] && echo "$f"
done  # | xargs rm

检查列表,如果看起来正常,则删除最后一行的# 以实际删除不需要的文件。

为什么使用head -4?因为wc 不知道什么时候退出。假设有一半的文本文件每个都超过 1 TB 长;如果是这样的话,单独wc -l 会很慢。

【讨论】:

    【解决方案3】:

    您可以使用wc 计算行数,然后决定是否删除文件。您应该编写一个 shell 脚本,而不仅仅是 awk 命令。

    【讨论】:

      【解决方案4】:

      你可以试试 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
      
      $
      

      【讨论】:

        猜你喜欢
        • 2014-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-22
        • 1970-01-01
        • 2015-12-22
        相关资源
        最近更新 更多