Wie bearbeite ich mehrere Textdateien mit einem einzigen Befehl?

18

Ich möchte die erste Zeile mehrerer Textdateien entfernen und durch eine andere Zeile ersetzen. Gibt es eine Möglichkeit, dies über das Terminal zu tun?

Ich weiß, wie man vim benutzt. Gibt es eine Möglichkeit, es damit zu automatisieren? Ich möchte es vermeiden, es manuell zu tun (wie beim Bearbeiten jeder Datei einzeln).

Wenn möglich, möchte ich die Installation neuer Bibliotheken vermeiden (insbesondere für solche, die ich für sehr einfach halte - aber ich könnte mich irren).

Danke im Voraus!

TomTsagk
quelle

Antworten:

21

Sie können verwenden sed:

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

Dadurch wird die erste Zeile aller .txtDateien im aktuellen Verzeichnis durch den Text ersetzt new line. Ändern Sie ihn entsprechend Ihren Anforderungen.

Auch die Originaldateien werden mit der .bakErweiterung gesichert , wenn Sie dies nicht möchten, verwenden Sie einfach:

sed -i '1s/^.*$/new line/' *.txt
heemayl
quelle
Vielen Dank! sedist eigentlich das, wonach ich gesucht habe!
TomTsagk
@ TomTsagk Ich bin froh, dass ich helfen konnte :)
Heemayl
11

Nun, mit sich vimselbst:

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

Was dies bewirkt:

  • setline (n, text)ist eine Funktion, die line nauf setzt text.
  • call wird benötigt, um Funktionen aufzurufen.
  • bufdo wird verwendet, um einen Befehl über Puffer hinweg zu wiederholen (ohne einen Bereich wirkt er auf alle Puffer).
  • wqSpeichert und verlässt den Puffer. Dies müssen wir tun, bevor wir mit dem nächsten Puffer fortfahren, damit dieser Befehl mit dem callBefehl verkettet wird |.
  • -c cmdrunning cmdist ein Kommando-Mode-Kommando nach dem Laden des ersten Puffers.
  • Nes Aktiviert den nicht kompatiblen, stillen Ex-Modus, der besser für die nicht interaktive Verarbeitung geeignet ist.

Leistungen:

  • Der setlineTextinhalt kann beliebig sein - ein &in einem sedErsetzungstext kann unbeabsichtigte Auswirkungen haben.
muru
quelle
sedscheint viel einfacher zu bedienen zu sein, aber es ist wirklich großartig, vimdas gleiche zu tun! Vielen Dank für Ihre Antwort!
TomTsagk
@TomTsagk Nun, ich wollte nur veranschaulichen, wie Sie sich über mehrere Dateien hinweg verhalten können ( bufdo). Stellen Sie sich vor, Sie haben die Dateien bereits geöffnet und ... und zeigen eine Alternative zu 1s/foo/bar/.
muru
Ehrfürchtig !!! <3_ <3
Campa
3

Ein paar andere Möglichkeiten:

  • awk(benötigt eine relativ neue Version von 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
    
terdon
quelle
2

Dieses Skript führt die von Ihnen angeforderten Schritte aus und legt die geänderten Dateien in einem neuen Verzeichnis ab, ohne die Originale tatsächlich zu ändern.

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
Charles Boling
quelle
Ich antwortete langsam (testete meinen Code) ... und ich mag Heemayls Lösung viel besser!
Charles Boling
0

Verwenden gawk

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

Beispiel

% 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
AB
quelle
0

jEdit: Ich benutze es zum Massen-Finden und-Ersetzen. Es ist leistungsstark mit der Fähigkeit, RegEx - Regular Expressions zu verwenden. Sie können Dateien in einem Verzeichnis bearbeiten, Dateierweiterungen angeben, z. B. ".html" usw. Sie können das Gebietsschema der Kandidatenänderung im Kontext in einer GUI anzeigen. jEdit ist großartig.

jEdit ist über Ubuntus Software-Center verfügbar.

Roger
quelle
0

Die Befehle tail und cat würden dies leicht tun:

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

Schließen Sie diese in eine geeignete Schleife ein und verwenden Sie möglicherweise eine richtige und aufrichtige temporäre Datei anstelle eines fest codierten temporären Dateinamens. Ich glaube, dass Bash und andere Shells eine Syntax zum Erstellen temporärer Dateien haben.

Die Option -n von tail hat zwei Interpretationen, abhängig davon, ob das Argument ein Pluszeichen hat. Wenn es ein Pluszeichen hat, bedeutet dies, dass das Ende der Datei ab der angegebenen Zeilennummer angezeigt wird. Ansonsten ist die Anzahl die Anzahl der Zeilen, einschließlich der letzten Zeile, die der Schwanz ausgeben soll.

Cardiff Space Man
quelle