Como editar vários arquivos de texto com um único comando?

18

Eu quero remover a primeira linha de vários arquivos de texto e substituí-la por outra linha. Existe uma maneira de fazer isso usando o terminal?

Eu sei como usar o vim, existe uma maneira de automatizar isso? Eu quero evitar fazer isso manualmente (como na edição de cada arquivo individualmente).

Se possível, gostaria de evitar a instalação de novas bibliotecas (especialmente para algo assim que considero muito simples - mas posso estar errado).

Obrigado antecipadamente!

    
por TomTsagk 02.08.2015 / 00:47

7 respostas

20

Você pode usar sed :

sed -i.bak '1s/^.*$/new line/' *.txt

Isso substituirá a primeira linha de todos os arquivos .txt no diretório atual pelo texto new line , altere-o para atender às suas necessidades.

Também será feito backup dos arquivos originais com a extensão .bak , se você não quiser, use:

sed -i '1s/^.*$/new line/' *.txt
    
por heemayl 02.08.2015 / 00:57
11

Bem, usando vim em si:

vim -Nesc 'bufdo call setline(1,"This is the replacement.") | wq' file1 file2 ...

O que isso faz:

  • setline (n, text) , bem, é uma função que define a linha n to text .
  • call é necessário para chamar funções.
  • bufdo é usado para repetir um comando nos buffers (sem um intervalo, ele age em todos os buffers ).
  • wq salva e sai do buffer. Precisamos fazer isso antes de passar para o próximo buffer, então este comando está encadeado no comando call usando | .
  • -c cmd runs cmd é um comando de modo de comando depois de carregar o primeiro buffer.
  • Nes ativa o modo não compatível, silencioso, ex, o que é melhor para o processamento não interativo.

Benefícios:

  • O conteúdo do texto setline pode ser qualquer coisa - um texto & em um texto de substituição sed pode ter efeitos indesejados.
por muru 02.08.2015 / 01:16
3

Algumas outras opções:

  • awk (precisa de uma versão relativamente nova do GNU awk )

    $ awk -i inplace -vline="new line" '(FNR==1){print line; next}1;' *.txt
    
  • Perl / shell

    $ for f in *txt; do
        perl -i -lne '$.==1 ? print "new line" : print' "$f"
      done
    
  • Shell / coreutils

    $ for f in *txt; do 
        ( echo "new line"; tail -n+2 "$f" ) > foo && mv foo "$f"; 
      done
    
por terdon 02.08.2015 / 10:18
2

Este script fará o que você pediu, colocando os arquivos alterados em um novo diretório sem realmente alterar os originais.

d=/tmp/cooked
mkdir $d
for f in *  #will match all files in current directory; adjust as desired
do
  echo "This is the new 1st line" > /${d}/${f}
  sed 1d ${f} >> /${d}/${f}
done
    
por Charles Boling 02.08.2015 / 01:04
0

Usando gawk

gawk -i inplace 'FNR==1 {$_="your_replacement"}; {print}' *.txt

Exemplo

% cat foo.txt 
1
2
3
4

% cat bar.txt 
1
2
3
4

% gawk -i inplace 'FNR==1 {$_="your_replacement"}; {print}' *.txt

% cat foo.txt                                                    
your_replacement
2
3
4

% cat bar.txt                                                    
your_replacement
2
3
4
    
por A.B. 02.08.2015 / 11:30
0

jEdit: eu uso para encontrar e substituir em massa. É poderoso com a capacidade de usar o RegEx - Expressões Regulares. Você pode operar arquivos em um diretório, especificar extensões de arquivos, por exemplo, ".html" e assim por diante. E você pode ver o local da mudança do candidato no contexto, em uma GUI. jEdit é ótimo.

O jEdit está disponível através do centro de software do Ubuntu.

    
por Roger 10.08.2015 / 22:02
0

Os comandos tail e cat fariam isso facilmente:

tail -n +1 $file > tmpfile
cat newfirstline tmpfile >$file

Agrupe-os em um loop adequado e, talvez, use um arquivo temporário correto e correto, em vez de um nome de arquivo temporário codificado. Eu acredito que o bash e outros shells têm uma sintaxe para criar arquivos temporários.

A opção -n de tail tem duas interpretações, dependendo de o argumento ter um sinal de mais. Se tiver um sinal de mais, significa mostrar a cauda do arquivo começando em o número da linha dada. Caso contrário, o número é o número de linhas, incluindo a última linha, que a cauda deve gerar.

    
por cardiff space man 03.09.2015 / 19:55