Passando curinga * para um script (bash?)

Passando curinga * para um script (bash?)

Quero remover todos os códigos de cores parecidos com '@n', '@R' etc., de uma coleção de arquivos de texto de tamanho moderadamente grande.

Então, em um arquivo chamado ‘remove_cc’, escrevi o seguinte:

sed -ie 's/@r//g' $1
sed -ie 's/@g//g' $1
sed -ie 's/@y//g' $1
sed -ie 's/@b//g' $1
sed -ie 's/@m//g' $1
sed -ie 's/@c//g' $1
sed -ie 's/@n//g' $1
sed -ie 's/@R//g' $1
sed -ie 's/@G//g' $1
sed -ie 's/@Y//g' $1
sed -ie 's/@B//g' $1
sed -ie 's/@M//g' $1
sed -ie 's/@C//g' $1
sed -ie 's/@N//g' $1
sed -ie 's/@W//g' $1
sed -ie 's/@K//g' $1

De qualquer forma, o script funciona perfeitamente se eu usá-lo como: ./remove_cc file.txt

Mas se eu digitar ./remove_cc *.txtuma pasta com muitos arquivos txt nos quais desejo executar o script, ele não conseguirá fazer nada. ./remove_cc *é igualmente ineficaz.

Existe uma maneira de consertar isso para que funcione?

Responder1

Quando você digita ./remove_cc *, o shell muda para ./remove_cc file1.txt file2.txt file3.txt etce executa seu script dessa maneira. Seu script está olhando apenas para $1o primeiro parâmetro (arquivo1.txt).

A maneira mais geral de fazer isso é percorrer cada parâmetro por vez. "$@"expande para a lista de todos os parâmetros e podemos usá for-los para fazer um loop sobre eles.

for n in "$@" ; do
    sed -ie 's/@r//g' "$n"
    ...
done

Neste caso específico, como sedserão necessários vários nomes de arquivos, você pode simplificar:

sed -ie 's/@r//g' "$@"

Observe que prestar atenção às aspas é importante ao escrever scripts de shell. Sem as aspas, por exemplo, o script não funcionaria em um arquivo chamado My Text File.txt.

Responder2

Apenas use

 for x in *
 do
     ./remove_cc $x
 done

A propósito, você pode combinar todos os sed em uma linha

sed -i \
    -e 's/@r//g' -e 's/@g//g' -e 's/@y//g' -e 's/@b//g' \
    -e 's/@m//g' -e 's/@c//g' -e 's/@n//g' -e 's/@R//g' \
    -e 's/@G//g' -e 's/@Y//g' -e 's/@B//g' -e 's/@M//g' \
    -e 's/@C//g' -e 's/@N//g' -e 's/@W//g' -e 's/@K//g' \
    $1

você também pode juntar comandos sed com ponto e vírgula:

sed -i -e 's/@r//g;s/@g//g;s/@y//g' $1

ou apenas use a lista de caracteres

sed -i -e s/@[rgbcmyRGBCMY]//g $1

ou

 sed -i -e s/@[rgbcmyRGBCMY]//g *

(certifique-se de verificar se coloquei toda a carta)

Responder3

Use "$@"em vez de $1. Ou cite o curinga:

$ bash -c 'echo $1' 'some command' '*'
file1 file2
$ bash -c 'echo "$@"' 'some command' *
file1 file2

Responder4

Se você não deseja alterar seu script você também pode usar xargs (considerando que você o possui ou está disponível em sua plataforma) executando-o assim:

ls *.txt | xargs -L1 ./remove_cc

xargs é um utilitário que pega stdin e o transforma em parâmetros de comando em um comando a ser executado. Possui o sinalizador -L que limita a quantidade de linhas de entrada a serem utilizadas em uma única execução.

informação relacionada