【问题标题】:How can I reduce one of the pipe in the following awk statement如何减少以下 awk 语句中的管道之一
【发布时间】:2012-10-23 13:56:24
【问题描述】:

ls -lrt | awk ' !/dly/ { print $NF } ' | awk ' /000001.txt.gz/ { print } '

我想显示符合以下条件的文件名: 1) 不应包含“dly”关键字。 2)应包含“000001.txt.gz”关键字。

我使用了上面的命令。是否可以合并我使用的 2 个管道?

【问题讨论】:

  • 旁注。你是说. 还是\.

标签: linux bash shell awk


【解决方案1】:

这不使用awk,但确实减少了管道的数量。

find -name "*dly*" -o -name "*000001.txt.gz*" -exec basename {} \;

编辑:添加了 Zack 建议的更改(对于 GNU find

find -maxdepth 1 -name "*dly*" -o -name "*000001.txt.gz*" -printf '%f\n'

【讨论】:

  • 啊,是的,我的错 - 我偶尔会忘记 find 不遵循“预期的”关联性和优先级规则。
  • 如果你有 GNU 查找,你可以用 -printf '%f\n' 替换 -exec basename {} \; 另外,为了精确匹配原来的,应该有一个 -maxdepth 1 在某处。
【解决方案2】:

您可以将awk 中的条件组合起来,就像它们是 C 表达式一样,所以

ls -lrt | awk '/000001\.txt\.gz/ && !/dly/ { print $NF }'

应该可以。 (根本没有经过测试。)但是,如果您希望针对不寻常的事情(例如文件名中的空格)提高效率和鲁棒性,那么您应该这样做:

ls -1rt | awk '/000001\.txt\.gz/ && !/dly/ { print }'

只要您的文件名中没有换行符,这将是可靠的。 (only 字节值 - not 个字符;内核不知道字符编码 - 不能出现在路径名组件中的是 0x2F 和 0x00,但您通常没有除非您正在编写一个必须处理 恶意 文件名的脚本,否则不必担心这一点。)另一种选择是寻找一种更强大的语言,可以做到opendir

perl -le 'opendir(my $dh, ".") or die;
          print for sort grep { /00001\.txt\.gz/ && !/dly/ } readdir $dh'

或更简洁(但效率较低)

perl -le 'print for sort grep { /00001\.txt\.gz/ && !/dly/ } glob("*")'

不过,这与 ls -rt 的排序方式不同。我不记得你是如何在 Perl 中做到这一点的。

【讨论】:

  • 我猜如果文件名有空格可能会失败。或者如果文件名是000001ptxt1gz。或者,如果文件的所有者名称中有 dly。也许ls | awk '/000001\.txt\.gz/ && !/dly/ { print $0 }' 更准确。
  • 好吧,真的做到这一点的方法是完全不使用ls(见编辑)。不过,关于点和空格的观点很好。
  • 我喜欢perl。现在它值得 +1
【解决方案3】:
ls -lrt | awk ' !/dly/ && $NF~/000001.txt.gz/ { print $NF }'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2010-10-14
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 2022-01-21
    相关资源
    最近更新 更多