Como usar a saída de comando (ls) na entrada de outro comando (sox)?

1

Eu tenho uma pasta com vários arquivos .wav que estou tentando concatenar em ordem, mas acho que sou muito inexperiente com comandos bash para fazer isso da forma mais eficiente possível. Você vê, eu não sei como usar um conteúdo de arquivos como entrada para um comando:

Eu obtenho todos os nomes dos arquivos na ordem correta com:

ls *.wav | sort -V > script

Script:

ep1-s1.wav
ep2-s1.wav
ep3-s1.wav

Eu adiciono '\' após cada linha a ser usada no comando

lam script -s " \" > script2

Script2:

ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav \

Eu apago o último '\':

sed '$ s/.$//' script2 > script3

Script3:

ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav

E agora eu quero usar o conteúdo desse arquivo para o sox , como:

sox ep1-s1.wav \
ep2-s1.wav \
ep3-s1.wav output.wav

Como posso conseguir isso?

Agora, provavelmente há uma maneira de fazer isso em um único comando, mas não consegui descobrir como funciona o piping: se você sabe, eu adoraria saber!

    
por Bart 21.05.2018 / 21:45

3 respostas

2

Como mencionei em um comentário, se você não precisar da classificação da versão ( sort -V ), basta fazer sox *wav . No Linux, *wav passará por expansão de nome de arquivo, resultando em uma lista de nomes de arquivos classificados alfabeticamente. Isso é afetado por suas configurações de localidade, particularmente LC_COLLATE , que você pode usar no Google para obter mais informações.

Se você precisar de sort -V , a maneira correta de lidar com isso é com sequências de caracteres e matrizes terminadas com nulo para manipular nomes de arquivos com espaços e outros caracteres especiais. Esse script colocará a saída do comando sort em uma matriz e executará sox com essa lista.

#!/bin/bash

unset wav_files

while IFS= read -r -d '' file; do
   wav_files+=("$file")
done < <(find . -maxdepth 1 -type f -name "*wav" -print0 | sort -V -z)

if (( ${#wav_files[@]} == 0 )); then
   echo "No wav files found"
else
   sox -- "${wav_files[@]}"
fi

Isso pode ser mais do que você esperava, mas é uma boa prática;)

    
por 21.05.2018 / 23:10
0

Se e somente se seus nomes de arquivos forem "legais" e não contiverem espaços em branco ou caracteres especiais (especialmente caracteres glob), a saída fácil é executar sort em um comando substituição:

sox $(printf "%s\n" *.wav | sort -V) output.wav

O printf aqui funciona para colocar novas linhas ( \n ) após cada nome de arquivo.

(Como de costume, uma expansão sem aspas como essa será quebrada se os nomes dos arquivos tiverem espaços ou tabulações (eles serão divididos em dois depois que o $(...) for expandido) ou novas linhas (eles serão divididos em dois antes dos caracteres sort ) ou glob ( *?[] , eles serão expandidos para qualquer nome de arquivo correspondente) .Portanto, não faça isso se você não sabe que os nomes dos arquivos são bons o suficiente. Veja, por exemplo, link e Quando é necessário fazer uma cotação dupla?

    
por 22.05.2018 / 09:30
-2

Por que não tentar:

sox 'ls *.wax | sort -V'
    
por 21.05.2018 / 22:23