Transmitir curinga * para um script (bash?) [duplicado]

4

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

Então, em um arquivo chamado 'remove_cc', eu 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 fantasticamente se eu usá-lo como: ./remove_cc file.txt

Mas se eu digitar ./remove_cc *.txt em uma pasta com muitos arquivos txt em que quero executar o script, ele não fará nada. ./remove_cc * é igualmente ineficaz.

Existe uma maneira de corrigir isso para funcionar?

    
por roo 06.10.2014 / 20:06

4 respostas

8

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

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

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

Nesse caso específico, como sed terá vários nomes de arquivos, você poderá simplificar:

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

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

    
por 06.10.2014 / 20:22
8

é só usar

 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 unir 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 *

(não se esqueça de colocar toda a carta)

    
por 06.10.2014 / 20:15
1

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

$ bash -c 'echo $1' 'some command' '*'
file1 file2
$ bash -c 'echo "$@"' 'some command' *
file1 file2
    
por 06.10.2014 / 20:15
1

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

ls *.txt | xargs -L1 ./remove_cc

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

    
por 06.10.2014 / 21:26