Canaliza a saída de um comando para o comando rm

4

O seguinte comando imprime o caminho da música que está sendo reproduzida.

mpc | head -n 1 
songs/oldSongs/Mukesh_D/041 KANHAIYA = YAAD AAYI ADHI RAAT KO.mp3

Posso apagar este arquivo modificando o comando que usei para imprimi-lo?

    
por Dilawar 17.11.2012 / 14:53

5 respostas

7

Para responder à sua pergunta mais geral, esse é o trabalho de xargs para obter uma lista de palavras na entrada padrão e convertê-la em uma lista de argumentos para um comando.

No entanto, xargs espera a lista como espaço, tabulação e nova linha (e possivelmente mais caracteres em branco dependendo da localidade e implementação de xargs) lista separada de palavras onde aspas simples, aspas duplas e barra invertida são usadas para escapar desses separadores (com comportamentos variados com relação ao aninhamento daqueles por diferentes implementações de xargs).

Se a entrada for uma lista terminada por novas linhas, a forma canónica a converter para o formato esperado pelo xargs é para escapar de cada caractere (embora apenas barras invertidas, aspas simples, aspas duplas, sublinhado (potencialmente), espaço e tabulação (e possivelmente outros espaços em branco se não forem no local C) sejam necessárias um caractere de barra invertida, o que podemos fazer com sed .

mpc | head -n 1 | sed 's/./\&/g' | xargs rm --

Note que algumas implementações de xargs têm um limite bastante baixo no comprimento máximo de linha que eles esperam em stdin, então você pode querer apenas escapar dos caracteres necessários com aqueles.

Com o GNU xargs , pelo menos, você não precisa fazer isso, você pode fazer:

mpc | head -n 1 | xargs -rd '\n' rm --

(também usando a opção -r específica do GNU para evitar a execução de qualquer comando se a entrada estiver vazia).

    
por 17.11.2012 / 17:31
4

Você pode fazer isso com rm -i "/path/to/music/library/$(mpc -f %file% | head -n 1)" . No entanto, esteja avisado que isso será interrompido se o nome do arquivo contiver uma nova linha. Como a saída de mpc -f %file% é relativa ao caminho da sua biblioteca de músicas, você precisa prefixar a saída.

    
por 17.11.2012 / 14:55
1
Pessoalmente, enquanto eu acho que xargs é divertido e tudo, eu meio que prefiro loops para esse tipo de coisa. Por quê? Bem, isso oferece mais flexibilidade ... e também oferece uma maneira bastante fácil de lidar com espaços:

mpc | head -n 1 | while read filename
do
  ls -al "$filename"  # Look at the file you're deleting
  rm -i "$filename"   # Ask if you want it deleted (or not)
done

Quando você usa um loop while assim, seus dados são bombeados para qualquer nome de variável que vem depois de "read"; Para referenciar a variável, você precisa do primeiro cifrão. As aspas estão lá para manipular espaços, para que não se pareçam com os delímetros. Loops como este, embora menos elegantes do que um simples one-liner, oferecem mais flexibilidade e são muito úteis a longo prazo.

    
por 06.01.2016 / 21:16
0

A menos que você seja capaz de produzir nomes de arquivos terminados em NULL (por exemplo, find -print0 ), você pode tentar citar os nomes dos arquivos passando por sed 's/^/"/;s/$/"/' , que adiciona as citações no início e no final de uma linha. Note, no entanto, que neste caso você precisa ter:

  • um arquivo por linha
  • sem aspas duplas nos nomes de arquivos

A vantagem é que você pode transformar arbitrariamente a saída (por exemplo, quando você decide não renomear, em vez de excluir ou quando você precisa remover partes da saída).

    
por 17.11.2012 / 17:13
0

Se for seguro assumir que você não tem arquivos com aspas duplas ou novas linhas que você possa fazer:

mpc | head -n 1 | sed  's/^/"/g ; s/$/"/g' | xargs rm --

O sed adiciona aspas ao redor do seu nome de arquivo, e xargs transforma a entrada que recebe em argumentos para o comando que está executando (neste caso, o comando rm).

    
por 17.11.2012 / 20:08