Hoje veremos uma dupla considerada diabólica no shell, se utilizada sem a devida atenção: o find e o xargs.
O find, como o nome diz, é utilizado para se encontrar arquivos no sistema. Já o xargs facilita a repetição de um certo comando para cada entrada fornecida pra ele. Peraí, vamos entender melhor. Considere que eu queira apagar os arquivos terminados em ~ no diretório atual. Poderíamos utilizar a dupla da seguinte maneira:
Aqui o find retornaria uma saída com os arquivos terminados em ~ e o xargs executaria o comando rm para cada uma das saídas.
Por exemplo, crie um diretório teste e entre nele:
Agora crie os arquivos "teste" e "teste~":
Agora vamos apagar os arquivos terminados em ~ do diretório atual:
Olha aí o resultado acima, deu certo.
Até aí tudo bem, mas se o arquivos terminados em ~ possuíssem caracteres em branco? Experimente e crie um "teste 1~". Proteja-o com aspas para que o shell não interprete mal o que queremos:
Agora experimente apagá-lo com:
E agora, José? Cadê meu arquivo "teste"? Ele APAGOU O ARQUIVO ERRADO!
Isso aconteceu simplesmente porque o rm tratou o arquivo "teste 1~" como dois arquivos diferentes: um "teste" e outro "1~". Ou seja, o espaço em branco acabou com nossa alegria (e talvez o emprego)!
Mas não se apavore, pois uma solução pra isso é utilizar a opção -print0 do find junto com a opção -0 do xargs.
Pronto, agora sim, funcionou! A explicação é que o find separou os arquivos com um caractere nulo. O xargs interpretou os caracteres nulos como separadores dos arquivos e fez o que queríamos. :]
Para mais informações:
O find, como o nome diz, é utilizado para se encontrar arquivos no sistema. Já o xargs facilita a repetição de um certo comando para cada entrada fornecida pra ele. Peraí, vamos entender melhor. Considere que eu queira apagar os arquivos terminados em ~ no diretório atual. Poderíamos utilizar a dupla da seguinte maneira:
$ find . -name "*~" | xargs rm
Aqui o find retornaria uma saída com os arquivos terminados em ~ e o xargs executaria o comando rm para cada uma das saídas.
Por exemplo, crie um diretório teste e entre nele:
$ mkdir teste; cd teste
Agora crie os arquivos "teste" e "teste~":
$ > teste; > teste~
$ ls
teste teste~
Agora vamos apagar os arquivos terminados em ~ do diretório atual:
$ find . -name "*~" | xargs rm
$ ls
teste
Olha aí o resultado acima, deu certo.
Até aí tudo bem, mas se o arquivos terminados em ~ possuíssem caracteres em branco? Experimente e crie um "teste 1~". Proteja-o com aspas para que o shell não interprete mal o que queremos:
$ > "teste 1~"
$ ls
teste teste 1~
Agora experimente apagá-lo com:
$ find . -name "*~" | xargs rm
rm: imposível remover `1~': Arquivo ou diretório inexistente
$ ls
teste 1~
E agora, José? Cadê meu arquivo "teste"? Ele APAGOU O ARQUIVO ERRADO!
Isso aconteceu simplesmente porque o rm tratou o arquivo "teste 1~" como dois arquivos diferentes: um "teste" e outro "1~". Ou seja, o espaço em branco acabou com nossa alegria (e talvez o emprego)!
Mas não se apavore, pois uma solução pra isso é utilizar a opção -print0 do find junto com a opção -0 do xargs.
$ > teste
$ ls
teste teste 1~
$ find . -name "*~" -print0 | xargs -0 rm
$ ls
teste
Pronto, agora sim, funcionou! A explicação é que o find separou os arquivos com um caractere nulo. O xargs interpretou os caracteres nulos como separadores dos arquivos e fez o que queríamos. :]
Para mais informações:
$ man find
$ man xargs
Um comentário:
Tenho um wiki com comandos linux, e nele muitas anotações sobre o find:
http://linuxdicas.wikispaces.com/find
No meu blog tenho muita coisa sobre bash:
http://vivaotux.blogspot.com/search/label/bash
Postar um comentário