【问题标题】:An odd behavior of `find``find` 的奇怪行为
【发布时间】:2013-09-27 16:46:06
【问题描述】:

在我的fetch/evs/ 下,没有子文件夹,我有一个命令应该列出fetch/evs/*.ev 的所有不包含文本' Error 的文件:

find . -ipath '*/fetch/evs/*.ev' | xargs grep -L -e "' Error" > try0.txt

此命令返回 692 个文件。奇怪的是它忽略了满足条件的文件的一部分,例如,如果我这样做:

find . -ipath '*/fetch/evs/grades*.ev' | xargs grep -L -e "' Error" > try1.txt

此命令返回 72 个文件,它们根本不在 try0.txt 中。

我真的无法理解...有人可以帮忙吗?

Edit1:我才意识到我遗漏了一个非常重要的信息,实际上是在命令之后引发了一条消息:xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option。该命令在名称包含' 的文件处停止执行。为了纠正这个问题,我尝试了:

find . -ipath '*/fetch/evs/*.ev' | xargs -0 grep -L -e "' Error" > try3.txt

返回 xargs: argument line too long 和 0 个文件。

我也试过了:

find . -ipath '*/fetch/evs/*.ev' -print0 | xargs -0 grep -L -e "' Error" > try4.txt

根本停不下来....

有人知道吗?

【问题讨论】:

  • 可能是因为文件名中有空格。试试find . -ipath '*/fetch/evs/*.ev' -print0 | xargs -0 grep -L -e "' Error" > try0.txt。有用吗?
  • 为什么不使用grep-l 切换来列出匹配的文件?
  • 抱歉,我的意思是“”包含...
  • 返回 -print0xargs: Warning: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?xargs: argument line too long...
  • 顺便说一下,没有文件名包含空格...

标签: bash shell grep find xargs


【解决方案1】:

如果您要使用-exec,就不会遇到xargs: argument line too long 问题。

说:

find . -ipath '*/fetch/evs/*.ev' -exec sh -c "grep -L -e \"' Error\" {}" \;

使用sh 处理grep 模式中的单引号。

编辑:没有sh

find . -ipath '*/fetch/evs/*.ev' -exec grep -L -e "' Error" {} \;

【讨论】:

  • 谢谢...但是sh 不处理(,我得到了sh: 1: Syntax error: "(" unexpected 的文件名包含(
【解决方案2】:

这部分你的问题;

which returns xargs: argument line too long and 0 file.

是 find 返回的文件太多,无法适应最大命令行长度。可以使用 xargs 的 -n 选项来解决;

find . [snip] | xargs -n 5 ...

将导致 xargs 重复执行 ... 只有 5 个文件名而不是所有文件名。

【讨论】:

  • 这个命令让我有这个... argument line too ong ...-0选项,意思是解决'的问题。但是我尝试了... | xargs -n 5 -0 ...... | xargs -0 -n 5 ...,它们都不起作用...
【解决方案3】:

这不是一个确切的答案,但也太长了,无法发表评论。

这是一个 Perl 脚本,它可以模拟您的情况:

#!/usr/bin/env perl
use strict;
use warnings;
use File::Path qw(make_path);

my $subdir = "./fetch/evs";

make_path($subdir);

for my $i (0..999)
{
    {
    my $file1 = sprintf("%s/spare-%.3d.ev", $subdir, $i);
    open my $fh, '>', $file1 or die;
    printf $fh "Nothing to look at here\n" if ($i % 2 == 0);
    printf $fh "There is an ' Error ' here\n" if ($i % 2 == 1);
    close $fh;
    }
    {
    my $file2 = sprintf("%s/grades-%.3d.ev", $subdir, $i);
    open my $fh, '>', $file2 or die;
    printf $fh "Nothing to look at here\n" if ($i % 2 == 0);
    printf $fh "There is an ' Error ' here\n" if ($i % 2 == 1);
    close $fh;
    }
}

它在子目录fetch/evs(如果需要,它会创建)中创建 1,000 个名称为 spare-000.evspare-999.ev 以及 grades-000.evgrades-999.ev 的文件。奇数文件包含字符串' Error;偶数文件没有。

在 Mac OS X 10.8.5 上运行:

find . -ipath '*/fetch/evs/grades*.ev' | xargs grep -L -e "' Error"

列出所有偶数文件(不包含标签字符串)和

find . -ipath '*/fetch/evs/grades*.ev' | xargs grep -l -e "' Error"

列出所有奇数编号的文件(确实包含标签字符串)。因此,在 Mac OS X 上,您的问题不会重现。脚本在您的机器上运行正常吗? (创建一个新的子目录或至少将现有的子目录移到视线之外。)

如果这些命令在您的机器上运行,那么您列出的这些文件还有其他内容。如果这些命令在您的机器上不起作用,则说明您的机器存在根本问题(您上次重新启动是什么时候?)。

那么

【讨论】:

  • 感谢您的输入,对不起,我一开始没有提供所有信息...我更新了我的 OP...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-11
  • 2020-03-09
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 2012-10-13
  • 2016-12-09
相关资源
最近更新 更多