Ich habe folgenden Code:
sed -i "/#alias/a alias ll='ls -laGh'" /etc/zshrc
sed -i "/#alias/a alias l='ls -l'" /etc/zshrc
in der Datei /etc/zshrc habe ich:
#alias
aber beim Ausführen des Codes wird mir der folgende Fehler angezeigt:
sed: 1: "/etc/zshrc": invalid command code z
Ich verstehe nicht, was passiert
sollte sein:
#alias
alias ll='ls -laGh'
alias l='ls -l'
es hilft mir nichts in einer Zeile:
#alias
alias ll='ls -laGh' alias l='ls -l'
Antwort1
Hier gibt es zwei Probleme. Das erste ist, dass die macOS-Version von sed
ein explizites Argument für die -i
Option erfordert, das angibt, welche Erweiterung für die Sicherungsdatei verwendet werden soll. Wenn Sie kein Backup wünschen, müssen Sie danach ein leeres Argument übergeben ( sed -i '' ...
). SieheDasUndDasauf Stackoverflow.
Das zweite Problem ist, dass der a
Befehl vor dem einzufügenden String ein maskiertes Newline-Zeichen und danach ein Newline-Zeichen erfordert. Von der [ man
Seite]:
[1addr]a\
text Write text to standard output immediately before each attempt to
read a line of input, whether by executing the ``N'' function or
by beginning a new cycle.
Wenn Sie beides berücksichtigen, sollte das Folgende das gewünschte Ergebnis liefern:
sed -i '' "/#alias/a\\
alias ll='ls -laGh'
" /etc/zshrc
Wenn Sie explizite Zeilenumbrüche in der Befehlszeichenfolge vermeiden möchten, können Sie anstelle expliziter Zeilenumbrüche definieren nl=$'\n'
und dann verwenden . Wenn Sie mehrere Zeilen auf einmal hinzufügen möchten, würde ich eher eine Schleife verwenden, um einen Befehl zu konstruieren, der alle auf einmal hinzufügt:${nl}
sed
nl=$'\n'
sedcmd=""
for aliascmd in "alias ll='ls -laGh'" "alias l='ls -l'"; do
sedcmd+="a\\${nl}${aliascmd}${nl};"
done
sed -i '' "/#alias/ { ${sedcmd} }" /etc/zshrc
Oder, wenn Sie es vorziehen, mehrere Befehle auszuführen:
nl=$'\n'
sed -i '' "/#alias/a\\${nl}alias ll='ls -laGh'${nl}" /etc/zshrc
sed -i '' "/#alias/a\\${nl}alias l='ls -l'${nl}" /etc/zshrc
Wenn diese letzte Option immer noch nicht funktioniert, führen Sie sie aus set -x
und versuchen Sie es erneut. Vorausgesetzt, Sie verwenden zsh, sollten Sie ungefähr Folgendes sehen:
+zsh:10> sed -i '' $'/#alias/a\\nalias ll=\'ls -laGh\'\n' /etc/zshrc
+zsh:11> sed -i '' $'/#alias/a\\nalias l=\'ls -l\'\n' /etc/zshrc
(Nur die Zahlen +zsh:something
werden anders sein und es wird auch eine Menge irrelevantes Zeug über die Aktualisierung des Terminal-cwd geben.) Der einzige Grund, der mir einfällt, warum dadurch alles in eine Zeile gesetzt würde, ist, wenn der Zeilenumbruch am Ende des sed
Befehls fehlt:
+zsh:11> sed -i '' $'/#alias/a\\nalias l=\'ls -l\'\n' /etc/zshrc
^^
this bit here
Übrigens, verwenden Sie es set +x
, um die Debug-Verfolgung zu deaktivieren.