So fügen Sie mit sed auf dem Mac eine Phrase nach einem Wort ein

So fügen Sie mit sed auf dem Mac eine Phrase nach einem Wort ein

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 sedein explizites Argument für die -iOption 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 aBefehl vor dem einzufügenden String ein maskiertes Newline-Zeichen und danach ein Newline-Zeichen erfordert. Von der [ manSeite]:

 [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 -xund 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:somethingwerden 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 sedBefehls 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.

verwandte Informationen