Como usar o comando xargs no Linux

Um prompt de terminal Linux em um laptop
Fatmawati Achmad Zaenuri / Shutterstock

Precisa encadear alguns comandos do Linux, mas um deles não aceita entrada canalizada? xargs pode pegar a saída de um comando e enviá-la para outro comando como parâmetros.

Todos os utilitários padrão do Linux têm três fluxos de dados associados a eles. Eles são o fluxo de entrada padrão (stdin), o fluxo de saída padrão (stdout) e o fluxo de erro padrão (stderr).

Esses fluxos funcionam com texto. Enviamos a entrada (stdin) para um comando usando texto e a resposta (stdout) é gravada na janela do terminal como texto. As mensagens de erro também são gravadas na janela do terminal como texto (stderr).

Um dos grandes recursos do Linux e dos sistemas operacionais semelhantes ao Unix é a capacidade de canalizar a saída stdout de um comando para a entrada stdin de um segundo comando. O primeiro comando não se importa se sua saída não está indo para uma janela de terminal, e o segundo comando não se importa se sua entrada não está vindo de um teclado.

Embora todos os comandos do Linux tenham os três fluxos padrão, nem todos aceitam o stdout de outro comando como entrada para seu stdin. Isso significa que você não pode enviar entrada para eles.

xargsé um comando para construir pipelines de execução usando os fluxos de dados padrão. Usando xargspodemos fazer comandos como echo, rme mkdir aceitar a entrada padrão como argumentos.

O Comando xargs

xargsaceitará entrada canalizada. Ele também pode aceitar a entrada de um arquivo. xargsusa essa entrada como parâmetros para os comandos com os quais dissemos para trabalhar. Se não dissermos xargspara trabalhar com um comando específico, ele usará como padrão echo.

Podemos usar isso para demonstrar como xargssempre gerará uma única linha de saída, mesmo a partir de entrada de várias linhas.

Se usarmos a opção -1(listar um arquivo por linha) com ls, obteremos uma única coluna de nomes de arquivos .

ls -1 ./*.sh

v em uma janela de terminal

Isso lista os arquivos de script de shell no diretório atual.

Recomendado:  Como você monitora solicitações feitas por uma extensão do Google Chrome?

saída de ls em uma janela de terminal

Obtemos uma única coluna conforme o esperado. Se canalizarmos, xargso que obtemos?

ls -1 ./*.sh | xargs

ls -1 ./*.sh |  xargs em uma janela de terminal

A saída é gravada na janela do terminal, como um longo fluxo de texto.

ls canalizado através de xargs em uma janela de terminal

É esse recurso que permite xargsinserir parâmetros em outros comandos.

Usando xargs com wc

Podemos usar xargspara wccontar facilmente as palavras, caracteres e linhas em vários arquivos.

ls * .page | xargs wc

ls * .page |  xargs wc em uma janela de terminal

Isto é o que acontece:

  • lslista os arquivos * .page e passa a lista para xargs.
  • xargspassa os nomes dos arquivos para wc.
  • wc trata os nomes dos arquivos como se os tivesse recebido como parâmetros da linha de comando.

saída wc em uma janela de terminal

As estatísticas de cada arquivo são exibidas junto com um total geral.

Usando xargs com confirmação

Podemos usar a -popção (interativa) para xargssolicitar a confirmação de que estamos felizes com sua continuação.

Se passar uma cadeia de nomes de arquivos para touch, através xargs, touchirá criar os arquivos para nós.

echo 'um dois três' | xargs -p touch

echo 'um dois três' |  xargs -p touch em uma janela de terminal

O comando que vai ser executado é exibido e xargsespera que respondamos digitando “y” ou “Y”, ou “n” ou “N” e pressionando Enter.

Se você apenas pressionar Enter, será tratado como “n”. O comando só é executado se você digitar “y” ou “Y”.

xargs solicitando confirmação em uma janela de terminal

Nós pressionamos “y” e pressionamos Enter. Podemos usar lspara verificar se os arquivos foram criados.

é um dois três

saída de ls em uma janela de terminal

Usando xargs com vários comandos

Podemos usar vários comandos xargs usando a opção  -I (argumentos iniciais).

Esta opção define uma “string de substituição”. Sempre que o token para a string de substituição aparecer na linha de comando, os valores fornecidos  xargsserão inseridos.

Vamos usar o treecomando para ver os subdiretórios do diretório atual. A -dopção (diretório) faz treecom que os arquivos sejam ignorados e apenas relatados nos diretórios.

árvore -d

tree -d em uma janela de terminal

Existe um único subdiretório chamado “imagens”.

Em um arquivo chamado “diretórios.txt”, temos os nomes de alguns diretórios que desejamos criar. Podemos ver seu conteúdo usando cat.

cat directory.txt

cat directory.txt em uma janela de terminal

Vamos usar isso como dados de entrada para xargs. O comando que vamos usar é este:

cat directory.txt | xargs -I% sh -c 'echo%; mkdir% '

Isso se divide assim:

  • cat directory.txt | : Isso envia o conteúdo do arquivo directrories.txt (todos os novos nomes de diretório) para xargs.
  • xargs -I% : Isso define uma “string de substituição” com o token “%”.
  • sh -c : Isso inicia um novo subshell. O -c(comando) diz ao shell para ler os comandos da linha de comando.
  • ‘echo%; mkdir% ‘ : cada um dos tokens “%” será substituído pelos nomes de diretório que são passados  xargs. O echocomando imprimirá o nome do diretório; o mkdircomando criará o diretório.
Recomendado:  Por que os iPhones geralmente têm melhor qualidade de som do que o Android?

cat directory.txt |  xargs -I% sh -c 'echo%;  mkdir% 'em uma janela de terminal

Os diretórios são listados um por um.

saída de xargs em uma janela de terminal

Podemos usar treemais uma vez para verificar se os diretórios foram criados.

árvore -d

saída da árvore em uma janela de terminal

Copiando arquivos para vários locais

Podemos usar xargspara nos permitir copiar arquivos para vários locais com um único comando.

Vamos canalizar os nomes de dois diretórios xargs como parâmetros de entrada. Diremos xargspara passar apenas um desses parâmetros por vez para o comando com o qual está trabalhando.

Nesse caso, o comando é cp. Portanto, o efeito é chamar cpduas vezes, cada vez com um dos dois diretórios como parâmetro de linha de comando. O xargsparâmetro que permite que isso aconteça é a opção -n(número máximo). Vamos definir isso como um.

Também estamos usando a -vopção (detalhada) com cppara que ele relate o que está acontecendo.

echo ~ / Backups / ~ / Documents / page-files / | xargs -n 1 cp -v ./*.page

echo ~ / Backups / ~ / Documents / page-files / |  xargs -n 1 cp -v ./*.page em uma janela de terminal

Os arquivos são copiados para os dois diretórios, um de cada vez. cprelata cada ação de cópia de arquivo para que possamos vê-las ocorrendo.

saída de xargs e cp em uma janela de terminal

Excluindo arquivos em diretórios aninhados

Se os nomes dos arquivos contiverem espaços e caracteres estranhos – como caracteres de nova linha – xargsnão será possível interpretá-los corretamente. Podemos superar esse problema usando a opção -0 (terminador nulo). Isso diz xargspara usar o caractere nulo como o delimitador final para nomes de arquivos.

Vamos usar findneste exemplo. findtem sua própria opção para lidar com espaços em branco e caracteres estranhos em nomes de arquivos. É a opção -print0(nome completo, caractere nulo).

encontrar . -name "* .png" -tipo f -print0 | xargs -0 rm -v -rf "{}"

Isso se divide assim:

  • encontrar . -name “* .png” : find vai pesquisar no diretório atual “.” para objetos com nomes que correspondem a “* .png” que são arquivos ( type -f).
  • -print0 : os nomes serão encerrados com um caractere nulo e espaços e caracteres estranhos serão atendidos.
  • xargs -0 : xargs também vai considerar nomes de arquivos como terminados em nulo, e espaços e caracteres estranhos não causarão problemas.
  • rm -v -rf “{}” : rm vai ser prolixo e relatar o que está acontecendo ( -v). Ele será recursivo (-r) e examinará subdiretórios aninhados, e removerá arquivos sem solicitar ( -f). O “{}” é substituído por cada nome de arquivo.
Recomendado:  O que são “IOPS” e importam?

encontrar .  -name "* .png" -tipo f -print0 |  xargs -0 rm -v -rf "{}" em uma janela de terminal

Todos os subdiretórios são pesquisados ​​e os arquivos que correspondem ao padrão de pesquisa são excluídos.

Saída de rm em uma janela de terminal

Removendo diretórios aninhados

Digamos que desejamos remover um conjunto de subdiretórios aninhados. treevai nos deixar vê-los.

árvore -d

tree -d em uma janela de terminal

encontrar . -name "level_one" -tipo d printo | xargs -o rm -v -rf "{}"

Este comando usará find para pesquisar recursivamente no diretório atual. O destino da pesquisa é um diretório chamado “level_one”. Os nomes dos diretórios são passados xargspara rm.

encontrar .  -name "level_one" -tipo d printo |  xargs -o rm -v -rf "{}" em uma janela de terminal

As únicas mudanças significativas entre este comando e o comando anterior são: o termo de pesquisa é o nome do diretório superior e -type dindica findpara procurar por diretórios, não por arquivos.

saída de find e xargs e rm em uma janela de terminal

O nome de cada diretório é impresso à medida que é removido. Podemos verificar com tree:

árvore -d

tree -d em uma janela de terminal

Todos os subdiretórios aninhados são excluídos.

Excluindo todos os arquivos, exceto um tipo de arquivo

Podemos usar find, xargse rmpara excluir todos os arquivos separados um do tipo que deseja manter. É um pouco contra-intuitivo, mas fornecemos o nome do tipo de arquivo que desejamos manter , não o nome daqueles que desejamos excluir.

A -notopção informa findpara retornar os nomes dos arquivos que não correspondem ao padrão de pesquisa. Estamos usando a opção  -I (argumentos iniciais) com xargsmais uma vez. Desta vez, o token de string de substituição que estamos definindo é “{}”. Ele se comportará exatamente da mesma forma que o token de string de substituição que geramos anteriormente, que por acaso era um “%”.

encontrar . -tipo f -não - nome "* .sh" -print0 | xargs -0 -I {} rm -v {}

encontrar .  -tipo f -não - nome "* .sh" -print0 |  xargs -0 -I {} rm -v {} em uma janela de terminal

Podemos verificar com ls. Os únicos arquivos restantes no diretório são aqueles que correspondem ao padrão de pesquisa “* .sh”.

ls -l

saída de ls em uma janela de terminal

Criando um arquivo de arquivo com Xargs

Podemos usar findpara pesquisar arquivos e transferi-los  xargs  para tar, para criar um arquivo compactado.

Vamos pesquisar no diretório atual. O padrão de pesquisa é “* .page”, então vamos procurar por arquivos “.page”.

find ./ - name "* .page" -tipo f -print0 | xargs -0 -tar -cvzf page_files.tar.gz

find ./ - name "* .page" -tipo f -print0 |  xargs -0 -tar -cvzf page_files.tar.gz em uma janela de terminal

Os arquivos são listados conforme o esperado, conforme o arquivo compactado é criado.

saída de alcatrão em uma janela de terminal

O Mediador de Dados

Às vezes, você precisa de um pequeno andaime quando empilhar as coisas. xargspreenche a lacuna entre os comandos que podem bombear informações e os comandos que não foram criados para recebê-las.

Ambos xargse findtêm um grande número de opções. Você é encorajado a verificar suas páginas de manual para aprender mais.