Wie füge ich in Bash nach jeder Zeile in einer Datei eine Zeichenfolge hinzu?

112

Wie füge ich mit bash nach jeder Zeile in einer Datei eine Zeichenfolge hinzu? Kann man das mit dem Befehl sed machen, wenn ja wie?

Jason Volkoz
quelle

Antworten:

188

Wenn Sie seddie Bearbeitung über den -iParameter zulassen:

sed -e 's/$/string after each line/' -i filename

Wenn nicht, müssen Sie eine temporäre Datei erstellen:

typeset TMP_FILE=$( mktemp )

touch "${TMP_FILE}"
cp -p filename "${TMP_FILE}"
sed -e 's/$/string after each line/' "${TMP_FILE}" > filename
Tom DeGisi
quelle
Warum machst du touchdie temporäre Datei? Und ich würde den sedBefehl davon abhängig machen, dass der Erfolg des cpoder des Originals verloren gehen könnte.
Bis auf weiteres angehalten.
Ich habe die Datei berührt, um den temporären Namen schnell zu reservieren. Dies ist möglicherweise nicht erforderlich. Ich denke, Sie haben Recht damit, den Befehl sed vom Erfolg des CP abhängig zu machen. Warum bearbeiten Sie nicht den Code, um dieses Problem zu beheben? Ich werde kein bisschen dagegen haben! Ihr Tom
Tom DeGisi
Was ist mit dem Hinzufügen einer Zeichenfolge vor einer Zeile?
Oxwivi
10
@Oxwivi: sed -e 's/^/string after each line/' -i filename $ bedeutet Zeilenende. ^ bedeutet Zeilenanfang.
Tom DeGisi
Wenn ich in sed sed 's/^/string after each line/'pfeife , mache ich das , was ich erwarten würde (vor jeder Zeile), sed 's/^/string after each line/'aber nicht (es ersetzt die gesamte Zeile durch meine Anhängezeichenfolge). Was gibt? Irgendwelche Ideen @TomDeGisi?
Philadams
17

Ich benutze lieber awk. Wenn es nur eine Spalte gibt, verwenden Sie $0, andernfalls ersetzen Sie sie durch die letzte Spalte.

Einweg,

awk '{print $0, "string to append after each line"}' file > new_file

oder dieses,

awk '$0=$0"string to append after each line"' file > new_file
Optimus Prime
quelle
1
Zum Anhängen von Zeilennummern (wie in meinem Fall) kann man auch die NRVariable verwenden:awk '{print $0, NR}'
andrybak
2
@optimus Ich habe deine Methode ausprobiert, aber einen zusätzlichen Platz für sie bekommen. Hast du eine Idee, wie du sie entfernen kannst?
Adil Saju
@AdilSaju sed 's/ //g'das hat für meine Anforderung funktioniert, aber es wird Platz in jeder Zeile entfernen, das ist die Option gfür und überall in einer Zeile.
Eklavyaa
@ AdilSaju bitte Details hinzufügen. Besser eine neue Frage stellen.
Optimus Prime
@AdilSaju awk Entfernen , wie {print $0"string to append after each line"}.
Culip
8

Wenn Sie es haben, kann das Dienstprogramm lam (Laminat) dies tun, zum Beispiel:

$ lam filename -s "string after each line"
Martin Clayton
quelle
4
  1. Reine POSIX-Shell und sponge:

    suffix=foobar
    while read l ; do printf '%s\n' "$l" "${suffix}" ; done < file | 
    sponge file
  2. xargsund printf:

    suffix=foobar
    xargs -L 1 printf "%s${suffix}\n" < file | sponge file
  3. Verwenden von join:

    suffix=foobar
    join file file -e "${suffix}" -o 1.1,2.99999 | sponge file
  4. Shell - Tools paste, yes, head & wc:

    suffix=foobar
    paste file <(yes "${suffix}" | head -$(wc -l < file) ) | sponge file

    Beachten Sie, dass zuvor pasteein Tabulatorzeichen eingefügt wird $suffix.

Natürlich spongekann durch eine temporäre Datei ersetzt werden, danach mvüber den ursprünglichen Dateinamen, wie bei einigen anderen Antworten ...

agc
quelle
1
Keines davon ist vorzuziehen sed, es sei denn, die Ressourcen sind sehr begrenzt.
Agc
Ich mag die nicht sedierte Lösung. sedwird für einen so einfachen Job nicht benötigt.
Bruce
1

Ich bevorzuge echo. mit reinem Bash:

cat file | while read line; do echo ${line}$string; done
Ox 的 Xiaox
quelle
-9

Sed ist ein bisschen hässlich, man könnte es elegant so machen:

hendry@i7 tmp$ cat foo 
bar
candy
car
hendry@i7 tmp$ for i in `cat foo`; do echo ${i}bar; done
barbar
candybar
carbar
hendry
quelle
2
Schlägt für Dateien mit mehr Zeilen als dem maximalen Argumentlimit der Shell fehl. Versuchen Sie: cat foo | während lesen a; echo $ {a} bar; erledigt oder so ähnlich; In den meisten Fällen ist es ein geeigneter Ersatz für.
alex
1
Es schlägt auch für Zeilen mit Leerzeichen fehl.
Bis auf weiteres angehalten.
1
Äh, nein, Dennis scheitert nicht. Shell maximale Argumentgrenze? Crikey du bist hängend.
Henry
Ja, das tut es: $ cat foo foo bar baz alex @ armitage: ~ $ für i in cat foo; echo $ {i} bar; getan foobar barbar bazbar, aber nach einigen Tests könnte ich mich in meiner Argumentation irren, aber Dennis hat recht
Alex
3
@hendry Ja, dies schlägt bei Zeilen mit Leerzeichen fehl, z. B. echo "foo bar" | (for i in `cat`; do echo ${i}bar; done)wenn 2 Zeilen gedruckt werden, obwohl die Eingabe 1 Zeile ist foo bar(und das catLesen von stdin anstelle einer Datei macht hierfür keinen Unterschied).
Hyde