Come modificare più file di testo con un singolo comando?

18

Voglio rimuovere la prima riga di più file di testo e sostituirla con un'altra linea. C'è un modo per farlo usando il terminale?

So come usare vim, c'è un modo per automatizzarlo con esso? Voglio evitare di farlo manualmente (come nel modificare ciascun file singolarmente).

Se possibile mi piacerebbe evitare l'installazione di nuove librerie (specialmente per qualcosa di simile che considero molto semplice - ma potrei sbagliarmi).

Grazie in anticipo!

    
posta TomTsagk 02.08.2015 - 00:47

7 risposte

20

Puoi utilizzare sed :

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

Questo sostituirà la prima riga di tutti i file .txt nella directory corrente con il testo new line , cambiandolo per soddisfare le tue necessità.

Anche i file originali verranno sottoposti a backup con l'estensione .bak , se non vuoi utilizzarli:

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

Bene, usando vim stesso:

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

Che cosa fa:

  • setline (n, text) , beh, è ​​una funzione che imposta la riga n su text .
  • call è necessario per chiamare le funzioni.
  • bufdo viene utilizzato per ripetere un comando tra i buffer (senza un intervallo, agisce su tutti i buffer ).
  • wq salva ed esce dal buffer. Dobbiamo farlo prima di passare al buffer successivo, quindi questo comando è incatenato al comando call usando | .
  • -c cmd runs cmd è un comando in modalità comando dopo aver caricato il primo buffer.
  • Nes attiva la modalità non compatibile, silenziosa, ex, che è meglio per l'elaborazione non interattiva.

Vantaggi:

  • Il contenuto di testo setline può essere qualsiasi cosa - un & in un testo di sostituzione sed può avere effetti indesiderati.
risposta data muru 02.08.2015 - 01:16
3

Alcune altre opzioni:

  • awk (richiede una versione relativamente nuova di 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
    
risposta data terdon 02.08.2015 - 10:18
2

Questo script farà come richiesto, posizionando i file modificati in una nuova directory senza cambiare effettivamente gli originali.

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
    
risposta data Charles Boling 02.08.2015 - 01:04
0

Uso di gawk

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

Esempio

% 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
    
risposta data A.B. 02.08.2015 - 11:30
0

jEdit: lo uso per ricerca di massa e sostituzione. È potente con la possibilità di usare RegEx - Regular Expressions. Puoi operare su file all'interno di una directory, specificare estensioni di file, ad esempio ".html" e così via. E, puoi vedere le impostazioni locali della modifica candidata nel contesto, in una GUI. jEdit è fantastico.

jEdit è disponibile tramite il software center di Ubuntu.

    
risposta data Roger 10.08.2015 - 22:02
0

I comandi tail e cat lo farebbero facilmente:

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

Avvolgi quelli in un ciclo appropriato e magari usa un file temporaneo appropriato e giusto invece di un nome di file temporaneo con codifica. Credo che bash e altre shell abbiano una sintassi per la creazione di file temporanei.

L'opzione -n ​​di tail ha due interpretazioni a seconda che l'argomento abbia un segno più. Se ha un segno più, significa mostrare la coda del file che inizia con il numero di linea indicato. Altrimenti il ​​numero è il numero di righe, inclusa l'ultima riga, che la coda dovrebbe produrre.

    
risposta data cardiff space man 03.09.2015 - 19:55

Leggi altre domande sui tag