Edite os arquivos com sed e salve o resultado em arquivos diferentes cujos nomes são baseados nos nomes dos arquivos originais

3

Eu tenho um conjunto grande (~ 300) de arquivos .csv, cada um com ~ 200k linhas de comprimento, com um padrão de nome de arquivo regular:

outfile_n000.csv
outfile_n001.csv
outfile_n002.csv
.
.
.
outfile_nXXX.csv

Eu preciso extrair um intervalo de linhas (100013-200013) de cada arquivo e salvar essa região extraída em um novo arquivo .csv, acrescentando um prefixo ptally_ para diferenciá-lo do arquivo original, preservando o original arquivo.

Eu sei que posso usar

sed -n '100013,200013p' outfile_nXXX.csv > ptally_outfile_nXXX.csv

para fazer isso em um único arquivo, mas eu preciso de uma maneira de automatizar isso para grandes lotes de arquivos. Eu posso chegar perto usando a opção -i in sed para fazer isso:

sed -iptally_* -n '100013,200013p' outfile_nXXX.csv > ptally_outfile_nXXX.csv

mas isso grava as linhas extraídas em outfile_nXXX.csv e deixa o arquivo original renomeado como ptally_outfile_nXXX.csv , pois essa é a finalidade de -i .

Da mesma forma, a expansão de chave no bash não fará o truque, já que a expansão de chave e os caracteres curinga não se misturam:

sed --n 10013,20013p *.csv > {,ptally_}*.csv

Quaisquer maneiras elegantes de combinar a extração e a renomeação em um processo mais simples? Atualmente, estou usando um script bash para realizar a troca entre os nomes de arquivos outfile_nXXX.csv e ptally_outfile_nXXX.csv , mas eu preferiria um fluxo de trabalho mais simples. Obrigado!

    
por avoyles 06.10.2017 / 01:38

2 respostas

5

Use um loop for .

for f in outfile_n???.csv; do
  sed -n '100013,200013p' "$f" > ptally_"$f"
done

Como alternativa, dependendo das suas necessidades reais, talvez seja mais aplicável usar csplit . Algumas das extensões GNU ampliam consideravelmente seu poder.

    
por 06.10.2017 / 06:20
2

Não sed , mas de maneira bem elegante:

awk 'NR >= 100013 && NR <= 200013 {print > "ptally_" FILENAME}' outfile_nXXX.csv

Para a extração em massa para arquivos novos e apropriados, faça o seguinte:

awk 'FNR >= 100013 && FNR <= 200013 {print > "ptally_" FILENAME}' outfile_n*

Além disso, você pode armazenar o nome do arquivo na variável antes de passá-lo ao sed :

filename="outfile_nXXX.csv"

sed -n '100013,200013p' "$filename" > "ptally_$filename"
    
por 06.10.2017 / 02:41

Tags