Aplicando a função bash para cada arquivo na subpasta recursivamente

4

Eu estou tentando escrever um script que irá aplicar uma função bash para cada arquivo em um diretório recursivamente. Por exemplo, se o diretório tests tivesse todos os meus arquivos e subdiretórios, o script

find tests -type f -print0 | xargs -0 echo

Funciona perfeitamente. Agora eu quero ser capaz de aplicar uma função bash ao invés de apenas ecoar, então eu inventei algo assim:

function fun() {
    echo $1
}

export -f fun

find tests -type f -print0 | xargs -0 bash -c 'fun "$@"'

No entanto, isso só gera um único arquivo nos testes, em que antes todos os arquivos são enviados. Eu esperaria que esses dois executassem o mesmo não?

    
por Ali Caglayan 22.11.2016 / 01:37

3 respostas

2

Use um script de shell.

Para citar esta excelente resposta :

Do other programs besides your shell need to be able to use it? If so, it has to be a script.

Como já foi observado em outras respostas, pode ser possível contornar isso exportando a função, mas é certamente um lote mais simples para usar apenas um script. / p>

#!/bin/bash
# I'm a script named "fun"!  :)
printf '%s\n' "$@"

Depois, basta colocar o script fun em algum lugar do PATH (talvez em ~/bin ), certificar-se de que ele é executável e executar:

find tests -type f -exec fun {} +
    
por 23.11.2016 / 00:44
1

Existem duas maneiras de resolver esse problema: você pode dizer ao xargs para executar o comando com apenas um argumento por vez usando -n1 ou loop para todos os argumentos dentro de sua função fun :

function fun() { echo $1 }
export -f fun
find tests -type f -print0 | xargs -n1 -0 bash -c 'fun "$@"' --

ou

function fun() { while [ -n "$1" ]; do echo $1; shift; done }
export -f fun
find tests -type f -print0 | xargs -0 bash -c 'fun "$@"' --
    
por 22.11.2016 / 04:07
0

Se você usa o GNU Parallel, é assim:

function fun() {
    echo "$@"
}
export -f fun

find tests -type f -print0 | parallel -0 -Xj1 fun
    
por 04.03.2017 / 15:30