Por que acabo com 4 invocações em vez de 3 ao usar este find -execdir {} + (plus)?

8

Eu leio aqui que você pode contar o número de invocações de command em -exec command {} + passando o | wc -l até o fim dele.

Embora eu entenda que -execdir é diferente, para cada subdiretório correspondente que find descobre, ele executa uma chamada do command do subdiretório no qual ele está contido, se eu tiver mais de um arquivo que corresponda em um subdiretório, não devo terminar com o número de chamadas igual ao número de subdiretórios correspondentes e não o número de chamadas correspondentes ao número de correspondências arquivos nesses subdiretórios?

Estou terminando com o último quando executo o seguinte:

$ find . -name "bob*" -execdir echo {} + | wc -l

A página man do execdir command {} + indica que o primeiro deve ser o caso:

As with the -exec action, the + form of the -execdir will build a command line to process more than one matched file, but any given invocation of command will only list files that exist in the same sub-directory.

ou seja,

Estou recebendo:

./file1inDir1
./file2inDir1
./file3InDir2
./file4InDir3

Quando estou esperando isso, com base na página do manual:

./file1inDir1 ./file2inDir1
./file3InDir2
./file4InDir3
    
por leeand00 27.01.2016 / 21:38

1 resposta

11

Este é um problema de desempenho de find . Em findutils versão 4.3.4, uma solução alternativa teve que restringir o número de argumentos que -execdir ... {} + usará para 1. Na versão 4.5.9 o limite foi removido.

Veja um exemplo:

$ mkdir -p dir{1..3}
$ touch dir{1..3}/file1 dir2/file{1..3}
$ find
.
./dir1
./dir1/file1
./dir2
./dir2/file1
./dir2/file2
./dir2/file3
./dir3
./dir3/file1

Com -execdir {} + , o comando deve ser executado 3 vezes. A segunda invocação deve ter 3 argumentos.

Com find 4.4.2:

$ find-4.4.2 . -name "file*" -execdir sh -c 'echo "Executing $@ in $(pwd)"' find-sh {} +
Executing ./file1 in /path/to/dir1
Executing ./file1 in /path/to/dir2
Executing ./file2 in /path/to/dir2
Executing ./file3 in /path/to/dir2
Executing ./file1 in /path/to/dir3

Com find 4.6.0:

$ find-4.6.0 . -name "file*" -execdir sh -c 'echo "Executing $@ in $(pwd)"' find-sh {} +
Executing ./file1 in /path/to/dir1
Executing ./file1 ./file2 ./file3 in /path/to/dir2
Executing ./file1 in /path/to/dir3
    
por 27.01.2016 / 23:33

Tags