Wie füge ich Text an den Anfang und das Ende mehrerer Textdateien in Bash an?

24

Ich habe ein Verzeichnis voller Textdateien. Mein Ziel ist es, Text an den Anfang und das Ende aller anzuhängen. Der Text am Anfang und am Ende ist für jede Datei gleich.

Basierend auf dem Code, den ich aus dem Web erhalten habe, ist dies der Code zum Anhängen am Anfang der Datei:

echo -e 'var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)' > $BASEDIR/Translations/Javascript/*.txt

Dies ist der Code zum Anhängen an das Ende der Datei. Ziel ist es, den Text };am Ende jeder Datei einzufügen:

echo "};" >> $BASEDIR/Translations/Javascript/*.txt

Die Beispiele, aus denen ich schöpfte, betrafen die Bearbeitung einzelner Akten. Ich dachte, ich würde versuchen, mit dem Platzhalter mehrere Dateien zu bearbeiten *.txt.

Ich könnte auch andere Fehler machen. Wie füge ich in jedem Fall Text an den Anfang und das Ende mehrerer Dateien an?

Fragesteller
quelle

Antworten:

27

Um einer Datei Text voran zu stellen, können Sie Folgendes verwenden (mit der GNU-Implementierung von sed):

sed -i '1i some string' file

Das Anhängen von Text ist so einfach wie

echo 'Some other string' >> file

Als letztes müssen Sie dies in eine Schleife einfügen, die alle Dateien durchläuft, die Sie bearbeiten möchten:

for file in *.txt; do
  sed -i '1i Some string' "$file" &&
  echo 'Some other string' >> "$file"
done
Marco
quelle
8

Sie können GNU sed verwenden

Wie bereits dargestellt, können Sie Textzeilen rechts einfügen vor und nach Zeilen einer Datei mit passenden sed, mit dem iund ajeweils Befehl. Was nicht gezeigt wurde, ist, dass Sie es mit einem Einzeiler und für mehrere Dateien gleichzeitig tun können .

Im Folgenden wird eine Zeile vor der ersten 1iund nach der letzten Zeile eingefügt $a. Die Einfügungen werden für alle Dateien ausgeführt, die mit dem Glob übereinstimmen *.txt.

sed -i -e '1ivar language = {' -e '$a};' -- *.txt

Beide iund afunktionieren nicht nur mit Zeilennummern, sondern auch mit jeder Zeile, die einem bestimmten Muster entspricht. Dies würde einen Kommentar einfügen, wenn eine Zeile enthält var y = 2;:

sed -i -- '/var y = 2;/i//initialize variable y' *.js
J. Katzwinkel
quelle
5

Vollständig POSIX-kompatibler Befehl mit ex:

for f in *.txt; do printf '%s\n' 0a 'var language = {' . '$a' '};' . x | ex "$f"; done

Wenn Sie den printfTeil des Befehls selbst ausführen, werden die genauen Bearbeitungsbefehle angezeigt, an die er übergeben wird ex:

0a
var language = {
.
$a
};
.
x

0abedeutet "Text nach Zeile 0 anhängen" (dh vor der ersten Zeile). Die nächste Zeile ist der Literaltext, der nach Zeile 0 " .angehängt" werden soll. Der Punkt ( ) in einer Zeile beendet den anzuhängenden Text.

$a bedeutet, dass nach der letzten Zeile der Datei ein Text angehängt wird.

x bedeutet, die Änderungen zu speichern und zu beenden.

Platzhalter
quelle
2

Hier ist eine Möglichkeit, dies in Perl zu tun:

for f in ./*txt; do
  perl -lpe 'BEGIN{print "First string"}END{print "Last string"}' "$f" > foo && 
  mv foo "$f";
done
terdon
quelle
@ StéphaneChazelas Hinzufügen -ianstelle dieser Dateisubstitution funktioniert nicht , es wird nur auf stdout gedruckt.
Oleh Prypin,
@OlehPrypin, in der Tat dein Recht. Kommentar gelöscht.
Stéphane Chazelas
1

Versuchen Sie es mit ex:

ex -s +'bufdo!1s/^/HEAD/|$s/$/TAIL/' -cxa *.foo

wo Befehle sind:

  • bufdo!führt die folgenden Befehle für jeden geöffneten Puffer / jede geöffnete Datei aus (Hinweis: Es handelt sich nicht um POSIX )
  • 1s/^/HEAD/- Fügt HEADText in die erste Zeile am Zeilenanfang ein
  • $s/$/TAIL/- fügt TAILText an die letzte Zeile am Ende der Zeile an

und Argumente sind:

  • -s - Silent / Quick-Modus
  • -cxa - Alle geöffneten Puffer / Dateien speichern und beenden
  • *.foo- alle Dateien im aktuellen Verzeichnis ( *) mit fooErweiterung, Nutzung **/*.foofür Rekursivität (nach der Aktivierung globstar: shopt -s globstar)
Kenorb
quelle
1
note bufdo ist nicht POSIX pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html
Steven Penny
1
@StevenPenny ist richtig. Ich verwende POSIX-spezifische Funktionen nur persönlich für geskriptete Bearbeitungen.
Wildcard
1

Mit gnu awk, unter Verwendung der inplaceErweiterung und BEGINFILE/ oder ENDFILE:

gawk -i inplace 'BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1' ./*.txt
don_crissti
quelle
1

Hat auch das Recht zu sein (mit Ergebnissen in .outDateien):

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.out' \;

Eine weitere, aufwändigere Variante - Quelldateien, die durch das Ergebnis ersetzt wurden:

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}' \; -print
Turm
quelle
0

Perl Einzeiler zur Rettung:

perl -i -pe'$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof' *.txt
Kjetil S.
quelle