Esvazie vários arquivos de log .csv, mas mantenha o cabeçalho

0

Eu tenho alguns arquivos de log .csv em dois subdiretórios de um diretório principal e quero esvaziar todos os arquivos de log .csv em cada diretório, mas reter o cabeçalho para que eles possam ser preenchidos novamente pelo aplicativo que os cria.

Eu posso usar for file in /path/to/file/*; do > $file;done para esvaziar os arquivos, mas o cabeçalho também é removido!

    
por Dwayne Pype 12.06.2018 / 16:19

2 respostas

1

tmpfile=$( mktemp )

for pathname in /path/to/dir/*.csv; do
    head -n 1 "$pathname" >"$tmpfile"
    cat "$tmpfile >"$pathname"
done

rm "$tmpfile"

Ou seja, extraia o cabeçalho usando head -n 1 para um arquivo temporário (supondo que seja apenas a primeira linha), trunque o arquivo original e insira o cabeçalho do arquivo temporário.

Se o cabeçalho for exatamente idêntico em todos os arquivos:

tmpfile=$( mktemp )
set -- /path/to/dir/*.csv

head -n 1 "$1" >"$tmpfile"

for pathname do
    cat "$tmpfile" >"$pathname"
done

rm "$tmpfile"

Isso primeiro define os parâmetros posicionais para a lista de arquivos nos quais estamos interessados e, em seguida, extrai o cabeçalho do primeiro deles. O loop itera sobre os parâmetros posicionais (os arquivos CSV) e trunca cada um, inserindo o cabeçalho.

Em ambos os exemplos acima, assume-se que o padrão /path/to/dir/*.csv corresponde a todos arquivos afetados. Um exemplo do mundo real de um padrão real pode ser

/var/log/myprogram/dir1/*.csv /var/log/myprogram/dir2/*.csv

ou, se você estiver usando um shell que compreenda a expansão de chaves:

/var/log/myprogram/{dir1,dir2}/*.csv
    
por 12.06.2018 / 16:23
0

Se você tem um sabor de sed que oferece uma opção --in-place ou -i , você pode substituir > "$file" por sed -i 4q "$file" , onde 4 é o número de linhas de cabeçalho que você deseja manter . Observe que algumas implementações podem exigir um arquivo de backup vazio explícito, por exemplo, -i '' .

Se o número de arquivos não for muito grande, talvez seja possível evitar o loop e simplesmente passar a lista de arquivos diretamente, por exemplo,

sed -si 4q subdir1/*.csv subdir2/*.csv

(o s é provavelmente supérfluo pelo menos no GNU sed, pois -i implica em -s )

ou use find

find path/to/dir -name '*.csv' -execdir sed -si 4q {} +

Veja como extrair apenas o nome do cabeçalho em um dado sem listar os dados em si

    
por 12.06.2018 / 16:47

Tags