An odd behavior of `find`

Refresh

December 2018

Views

195 time

1

Under my fetch/evs/, there is no sub-folder, I have a command which is supposed to list all the files of fetch/evs/*.ev which don't contain text ' Error:

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

This command returns 692 files. What is odd is that it ignores a part of files which satisfy the criteria, for instance if I do:

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

This command returns 72 files which are not in try0.txt at all.

I really cannot understand this... Could anyone help?

Edit1: I just realize that I omitted a very important information, actually a message is raised after the command: xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option. And the command does stop going through at a file whose name contains '. To correct this, I tried:

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

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

I also tried:

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

which does not stop at all....

Does anyone have any idea?

5 answers

1

Вы не столкнетесь с xargs: argument line too longвопросом , если вы должны были использовать -exec.

Сказать:

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

Использование shухаживает единой цитаты в grepшаблоне.

EDIT: Без sh:

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

Это точно не ответ, но это слишком долго, чтобы сделать в комментарии тоже.

Вот скрипт на 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;
    }
}

Это создает 1000 файлов с именами spare-000.evна spare-999.ev, а также grades-000.evв grades-999.evв подкаталоге fetch/evs(которые он создает при необходимости). Нечетные файлы содержат строку ' 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, ваша проблема не воспроизводится. Работает ли скрипт OK на вашей машине? (Создать свежий подкаталог или, по крайней мере, переместить существующий вне поля зрения.)

Если эти команды работают на вашей машине, то есть что-то еще о тех файлах, которые вы сделали список. Если эти команды не работают на вашем компьютере, существует фундаментальная проблема с машиной (когда вы в последний раз перезагрузиться?).

Тогда Whe

2

Это точно не ответ, но это слишком долго, чтобы сделать в комментарии тоже.

Вот скрипт на 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;
    }
}

Это создает 1000 файлов с именами spare-000.evна spare-999.ev, а также grades-000.evв grades-999.evв подкаталоге fetch/evs(которые он создает при необходимости). Нечетные файлы содержат строку ' 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, ваша проблема не воспроизводится. Работает ли скрипт OK на вашей машине? (Создать свежий подкаталог или, по крайней мере, переместить существующий вне поля зрения.)

Если эти команды работают на вашей машине, то есть что-то еще о тех файлах, которые вы сделали список. Если эти команды не работают на вашем компьютере, существует фундаментальная проблема с машиной (когда вы в последний раз перезагрузиться?).

Тогда Whe

2

Эта часть вашей проблемы;

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

является то, что найти возвращает слишком много файлов, чтобы соответствовать на максимальную длину командной строки. Может быть решены с помощью опции -n для xargs;

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

заставит xargs повторно выполнить ... только 5 имен файлов, а не все из них.

2

Это точно не ответ, но это слишком долго, чтобы сделать в комментарии тоже.

Вот скрипт на 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;
    }
}

Это создает 1000 файлов с именами spare-000.evна spare-999.ev, а также grades-000.evв grades-999.evв подкаталоге fetch/evs(которые он создает при необходимости). Нечетные файлы содержат строку ' 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, ваша проблема не воспроизводится. Работает ли скрипт OK на вашей машине? (Создать свежий подкаталог или, по крайней мере, переместить существующий вне поля зрения.)

Если эти команды работают на вашей машине, то есть что-то еще о тех файлах, которые вы сделали список. Если эти команды не работают на вашем компьютере, существует фундаментальная проблема с машиной (когда вы в последний раз перезагрузиться?).

Тогда Whe