Combinando sed com xargs para obter um nome de arquivo de origem e saída

3

Eu tenho uma situação em que tenho alguns arquivos de entrada como este:

M2U0001.MPG
M2U0180.MPG

E eu quero executar um comando (em um shell Bash) em cada arquivo de nome similar no diretório. Eu gostaria que o nome do arquivo atual fosse dado a esse comando como uma entrada e uma versão modificada do nome do arquivo a ser fornecida como um arquivo de saída. Aqui está um exemplo:

ffmpeg -i M2U0001.MPG M2U0001_fixed.MPG

Eu tive a ideia de usar o xargs e o sed, mas isso é o mais importante:

ls -1 *.MPG | xargs -I{} ffmpeg -i {} 'echo {} | sed -r 's/[0-9]{2,}/&_fixed/''

Mas isso resulta na saída do nome do arquivo original nas duas posições. Estou totalmente errado com isso?

Descobri que, se eu fizer o eco do nome do arquivo diretamente no bloco incorporado, funciona:

echo M2U0001.MPG | sed -r 's/[0-9]{2,}/&_fixed/'
    
por Matthew 12.11.2011 / 01:06

4 respostas

4

Ou alternativamente:

for i in *.MPG ; do ffmpeg -i $i 'basename $i .MPG'_fixed.MPG ; done

Obrigado joshbaptiste para o dica .

    
por 12.11.2011 / 02:22
2
find . -iname "*.mpg" -exec sh -c "ffmpeg -i {} 'echo {} | sed -e 's/\./_fixed\./''" \;
    
por 12.11.2011 / 01:53
2

for i in $(ls) não deve ser usado - a saída ls (1) não deve ser usada para análise por meio de scripts, etc. devido à divisão de palavras e é um erro comum que vejo em scripts Bash no meu trabalho.

Neste caso, a expansão de parâmetros funciona bem e não é suscetível a erros de divisão de palavras.

for i in *.MPG; do ffmpeg -i "$i" "${i%%.*}"_fixed.MPG ; done

Referência: link

    
por 15.11.2011 / 21:46
0

Aqui está uma variação específica:

ls -1 src/*.c | xargs -i sh -c "echo;gcc -fpreprocessed -dD -E {} 2>&1 | grep -wi -e one -e two -e three -n | sed 's:^:{}\::'" | cat -s

Uma lista de arquivos de origem C,

ls -1 src/*.c

é canalizado para xargs, que executa o pré-processador em um shell filho,

gcc -fpreprocessed -dD -E {} 2>&1

que é subsequentemente canalizado para um comando grep desejado

grep -wi -e one -e two -e three -n

que é então enviado ao sed para prefixar cada linha com o nome do arquivo atual:

sed 's:^:{}\::'

Finalmente, todas as linhas em branco repetidas são reduzidas a linhas simples usando cat:

cat -s

Isso funciona em um sistema Red Hat Linux 6, mas eu suponho que seja geral o suficiente para outros sistemas * nix.

    
por 06.06.2017 / 16:07

Tags