So hängen Sie mehrere Zeilen an eine Datei an


302

Ich schreibe ein Bash-Skript, um nach einer Datei zu suchen, wenn sie nicht existiert. Dann erstelle sie und hänge sie an:

Host localhost
    ForwardAgent yes

So "line then new line 'tab' then text"denke ich sein ein sensibles Format. Ich weiß, dass du das kannst:

cat temp.txt >> data.txt

Aber es scheint seltsam seit seinen zwei Zeilen. Gibt es eine Möglichkeit, das in diesem Format anzufügen:

echo "hello" >> greetings.txt

Antworten:


527
# possibility 1:
echo "line 1" >> greetings.txt
echo "line 2" >> greetings.txt

# possibility 2:
echo "line 1
line 2" >> greetings.txt

# possibility 3:
cat <<EOT >> greetings.txt
line 1
line 2
EOT

Wenn sudo (andere Benutzerberechtigungen) zum Schreiben in die Datei benötigt wird, verwenden Sie Folgendes:

# possibility 1:
echo "line 1" | sudo tee -a greetings.txt > /dev/null

# possibility 3:
sudo tee -a greetings.txt > /dev/null <<EOT
line 1
line 2
EOT

2
@TheLegend Das nennt man "hier Dokument". Schauen Sie sich diesen Absatz in der Manpage an.
Hauke ​​Laging

1
Eine weitere Möglichkeit ist ( echo "line 1" ; echo "line 2" ) >>greetings.txt.
ott--

2
@ott-- Du brauchst keine echte Subshell (dh du kannst einen neuen Prozess speichern), das ist genug:{ echo "line 1" ; echo "line 2"; } >>greetings.txt
Hauke ​​Laging

2
Was ist der Unterschied zwischen EOT und EOL?
Cikatomo

15
@cikatomo In cat <<EOTder EOTist nur eine zufällige Zeichenfolge. Könnte auch sein cat <<FOO.
Hauke ​​Laging

60
printf '%s\n    %s\n' 'Host localhost' 'ForwardAgent yes' >> file.txt

Oder, wenn es sich um eine wörtliche Registerkarte handelt, die Sie möchten (anstelle der vier Leerzeichen in Ihrer Frage):

printf '%s\n\t%s\n' 'Host localhost' 'ForwardAgent yes' >> file.txt

Sie können den gleichen Effekt mit erzielen echo, aber genau wie variiert von Implementierung zu Implementierung, während printfkonstant ist.



16

Ein anderer Ansatz ist zu verwenden tee

tee -a ~/.ssh/config << END
Host localhost
  ForwardAgent yes
END

Ein paar Auswahlzeilen aus teeder Manpage von:

Das Dienstprogramm tee kopiert die Standardeingabe in die Standardausgabe und erstellt eine Kopie in null oder mehr Dateien.

-a - Hängt die Ausgabe an die Dateien an, anstatt sie zu überschreiben.


6

SED kann eine Zeile wie folgt an das Ende einer Datei anhängen:

sed -i '$ a text to be inserted' fileName.file
$Wählt das Dateiende aus, afordert es zum Anhängen auf und danach folgt der einzufügende Text. Dann natürlich den Dateinamen.


Quelle: http://www.yourownlinux.com/2015/04/sed-command-in-linux-append-and-insert-lines-to-file.html

========== EDIT == ==========

Hat dieser Ansatz einen zusätzlichen Nutzen als andere Lösungen?
Ja, dieser Ansatz hat den zusätzlichen Vorteil, dass bei einer Suche an alle zurückgegebenen Dateien Folgendes angehängt wird: find . -name "*.html" -exec sed -i '$ a </html>' {} \;

Ich habe das obige Beispiel verwendet, um das End-HTML-Tag einzufügen, das auf jeder HTML-Seite in einer Reihe von Verzeichnissen fehlte.

==================================


1
Wenn Sie die Syntax zum Anhängen mehrerer Zeilen an eine Datei anzeigen würden, wäre dies eine Antwort auf die Frage (obwohl nicht sehr nützlich). Alle anderen Antworten schreiben Sie einfach den neuen Text. Diese Antwort liest die gesamte Datei und schreibt sie sowie den hinzugefügten Text neu. Hat dieser Ansatz Vorteile gegenüber den anderen?
G-Man

Dies funktioniert nur mit GNU sed. BSD sedbürgt mit dem Fehler: command a expects \ followed by text. Verwenden Sie dies also nicht für eine Skriptlösung. es kann brechen. (Oder machen Sie es richtig, da die von BSD benötigte Syntax POSIX-kompatibel ist und auch unter GNU funktioniert sed.
Wildcard

Die anderen Antworten können verwendet werden , findwie folgt: find . -name "*.txt" -exec sh -c 'printf "%s\n\t%s\n" "Host localhost" "ForwardAgent yes" >> "$1"' sh {} ";".
G-Man

1
Dies ist eine sehr gute Lösung, da sie keine Stream-Umleitung ( >, >>) ausführt und daher nicht unter Problemen wie dem Ausführen leidet sudo echo 'something' > /file. Für mich ist es erlaubt perfekt eine Zeile in eine Datei in lxd Behälter so anhängen: lxc exec c sed -- '$ a newline' /myfile.
Draco Ater

Es echo "a new line" >> foo.filewird keine neue Zeile erstellt, wenn die Datei nicht das Ende einer neuen Zeile ist sed -i '$ a a new line' foo.file, dies sedist jedoch der Fall. Dies ist besonders dann besser , wenn Sie der Datei immer eine neue Zeile hinzufügen möchten.
Zhouji

1

Ich habe sed verwendet, weil es mit sudo verwendet werden kann. Zum Beispiel:

sudo sed -i '$ a text to be inserted' fileName.file 

Die Alternative ist sehr hässlich wie:

sudo bash -c "echo a text to be inserted >> fileName.file"  

und noch hässlicher, wenn man mit ssh fertig ist.


1
Warum wurde diese Antwort abgelehnt? Das sieht nach der Lösung aus, die ich brauche. Gibt es ein Problem damit? Wenn nicht, benutze ich es und stimme ihm zu.
MountainX

sed -iNehmen Sie nicht eine Erweiterung als Argument? Ihr Beispiel enthält möglicherweise falsche Parameter.
Protometa

1

Ein weiterer Liner ist:

echo "Greetings 1" >> greetings.txt && echo "Greetings 2" >> greetings.txt

Ich würde den -eOptionsgedanken bevorzugen , da er mehr Kontrolle gibt:

echo -e "Greeting 1\nGreetings 2\n" >> greetings.txt

1

Man kann cat >> out.txtentweder mit Perl oder Python emulieren , um den gleichen Effekt zu erzielen. Perl:

perl -e 'open(fh,">>","./out.txt");while(<>){printf(fh "%s",$_)};close(fh);'

Und Python:

python -c 'import sys;f=open(sys.argv[1],"a");l=[i for i in sys.stdin];f.write("".join(l))' out.txt 

Beachten Sie, dass Sie für Python Ctrl+ Dzweimal drücken müssen . Weitere Informationen finden Sie in der entsprechenden Frage zum Stackoverflow .


1

Hier ist ein Beispiel zum Anhängen mehrerer Zeilen in einer Datei:

{
        echo '  directory "/var/cache/bind";'
        echo '  listen-on { 127.0.0.1; };'
        echo '  listen-on-v6 { none; };'
        echo '  version "";'
        echo '  auth-nxdomain no;'
        echo '  forward only;'  
        echo '  forwarders { 8.8.8.8; 8.8.4.4; };'
        echo '  dnssec-enable no;'
        echo '  dnssec-validation no;'
} >> your_file.txt

0

Zusätzlich zur Hauptantwort, falls die Datei Superuser-Berechtigungen benötigt, funktioniert das Hinzufügen sudovor echonicht.

Dies liegt daran, dass die Shell die Befehle unterbricht und zwar echoals root ausgeführt, jedoch >>mit normalen Berechtigungen ausgeführt wurde.

Dies funktioniert für Superuser: sudo su -c "echo 'Line 3' >> greetings.txt"


Du brauchst das suhier nicht ( sudo suist nicht gut). Aber Sie haben Recht damit, dass Sie etwas brauchen, um die Shell-Umleitung zu verwalten. vielleicht sudo sh -c "echo stuff >> file.txt". Keine Nettoersparnis, aber eine bessere Praxis.
Roaima
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.