【问题标题】:Use current filename ("{}") multiple times in "find -exec"?在“find -exec”中多次使用当前文件名(“{}”)?
【发布时间】:2015-03-01 22:50:03
【问题描述】:

许多消息来源说 {} 的每个实例都将替换为通过 find 找到的文件名,但是当我尝试运行以下命令时,我只得到一个文本文件,其名称为“.txt”

find /directory -name "*pattern*" -exec cut -f8 {} > {}.txt \;

我们的目标是创建一个文本文件,其中只有找到的每个文件的第八列,每个文本文件都将以其父文件命名。第二组 {} 的某些内容并未替换为每个找到的文件的文件名。

【问题讨论】:

    标签: shell find


    【解决方案1】:

    试试:

    find /directory -name "*pattern*" -exec sh -c 'cut -f8 {} > {}.txt' \;
    

    但请注意,某些版本的 find 要求 {} 是一个不同的参数,否则不会将 {} 扩展为文件名。您可以通过以下方式解决此问题:

    find /directory -name "*pattern*" -exec sh -c 'cut -f8 $0 > $0.txt' {} \;
    

    (此替代命令会将输出文件放在包含匹配文件的子目录中。如果需要,您可以通过重定向到${0#*/}来避免这种情况

    问题是find 没有进行重定向,shell 是。您的命令完全等同于:

    # Sample of INCORRECT code
    find /directory -name "*pattern*" -exec cut -f8 {} \; > {}.txt
    

    请注意标准中的以下内容:

    如果存在多个仅包含两个字符“{}”的参数,则行为未指定。

    如果实用程序名称或参数字符串包含两个字符 "{}" ,而不仅仅是两个字符 "{}" ,则由实现定义 find 是否替换这两个字符或使用字符串而不进行更改。

    【讨论】:

    • 我明白了,你的修复成功了。谢谢!我想知道 > 是否被误解了
    • 也许这对其他人来说是显而易见的,但该命令的sh 部分正在启动一个“子shell”,它可以让您执行更多“shell-y”的操作,如重定向等。看这个更多详细信息的好帖子。 unix.stackexchange.com/questions/389705/…
    【解决方案2】:

    要处理 William Pursell 在他的回答中提到的警告,请使用以下内容:

    find /directory -name "*pattern*" -exec sh -c 'cut -f8 "$1" > "$1.txt"' x {} \;
    

    当您使用sh -c 时,它会从要执行的字符串后面的参数中获取位置参数。多余的x填入$0,替换后的文件名会变成$1

    双引号允许它与包含空格和其他特殊字符的文件名正常工作。

    【讨论】:

    • 任何不使用 $0 的理由:sh -c '...$0...' {}?
    • 大多数情况下只是感觉“错误”——$0 应该是 shell 的名称,而不是参数。我不知道在那里使用它有多便携。
    【解决方案3】:
    find /directory -name "*pattern*" | xargs awk '{z=FILENAME".txt";print $8>z}'
    

    【讨论】:

      猜你喜欢
      • 2011-11-30
      • 2011-08-18
      • 2021-02-28
      • 1970-01-01
      • 2020-02-14
      • 2015-09-08
      • 1970-01-01
      • 2016-11-09
      相关资源
      最近更新 更多