Por que o redirecionamento da saída de loop depende do nome do arquivo?

0

Eu tenho dois arquivos: a.csv e b.csv :

echo $'a_header\na1' > a.csv
echo $'b_header\nb1' > b.csv

Agora quero remover a primeira linha de cada uma e concatená-las.

for file in 'ls *.csv'; do cat $file | tail -n +2 | cat; done 

No entanto, quando eu redireciono a saída do comando anterior para um arquivo, obtenho resultados diferentes dependendo do nome do arquivo de saída.

for file in 'ls *.csv'; do cat $file | tail -n +2 | cat; done > result
for file in 'ls *.csv'; do cat $file | tail -n +2 | cat; done > result.csv
cat result
a1
b1
cat result.csv
a1
b1
b1
    
por Miroslav Sabo 29.09.2015 / 11:06

1 resposta

2

Se você tiver o seguinte comando:

command > file

A saída padrão (fd 1) do comando command é redirecionada para o arquivo file . Se o arquivo não existir, ele será criado. Um comando normalmente redireciona sua saída de comando para o descritor de arquivo 1 (stdout).

Ao usar uma expressão como acima (em que a saída é redirecionada para um arquivo), o arquivo deve existir antes do início do fluxo de saída. Portanto, bash cria o arquivo (vazio) e conecta-se ao stdout de command , que então começa a escrever naquele descritor de arquivo.

Isso é tratado pelo shell. O comando não sabe se grava em um pipe anônimo ou em um arquivo.

Dado este comando:

for file in 'ls *.csv'; do cat $file | tail -n +2 | cat; done > result.csv

O que acontece aqui é que o arquivo result.csv é criado vazio. Em seguida, o loop for é executado em todos os arquivos cujo final é csv (incluindo result.csv ). Os arquivos são processados a.csv , depois b.csv e pelo menos result.csv . A segunda linha de result.csv em b1 . É por isso que você tem 2 linhas no arquivo de resultado.

    
por 29.09.2015 / 11:50