Wenden Sie den Befehl „expand“ direkt auf eine Datei an, z. B. sed -i

Wenden Sie den Befehl „expand“ direkt auf eine Datei an, z. B. sed -i

Der expandBefehl hat nicht das Äquivalent von

sed -i <file>

expandtatsächlich eine -iOption - aber es bedeutet

nur nach Leerzeichen

Gibt es eine seddynamische expandDuo-Kombination, um dasselbe Ziel zu erreichen?

Antwort1

Das GNU-Dienstprogramm expand bietet nicht die direkte Aktualisierung, die sed bietet. Es ist relativ einfach, dasselbe Ergebnis zu reproduzieren, obwohl der Befehl etwas länger sein kann.

Es ist nicht möglich, eine Datei gleichzeitig auf einem beliebigen Dateisystem zu analysieren und zu aktualisieren, ohne eine Beschädigung zu riskieren. Aus diesem und anderen Gründen führt sed dies nicht wirklich aus, obwohl es es vom Benutzer abstrahiert. Was sed tut (und Sie können es selbst reproduzieren), ist, dass es die Ausgabe seiner Operation an der Objektdatei in einer temporären Datei speichert, dann die Originalkopie löscht und die temporäre Datei in das Original umbenennt.

Hierfür gibt es zahlreiche Möglichkeiten. Hier ist eine davon: Die Datei mit dem Namen orig.txt ist die Datei, die „erweitert“ wird:

tmp=`mktemp` && expand orig.txt > "$tmp" && mv "$tmp" orig.txt

Wenn Sie nie andere Argumente als den Dateinamen zum Erweitern verwenden, expandkönnte eine einfache Funktion namens die gesamte temporäre Datei ausblenden und in die Originaldatei auslagern und das sedVerhalten reproduzieren - diese Implementierung würde ein einziges Argument für Pfad/Dateiname annehmen

expand() {
  [[ "$#" -ne "1" ]] && { echo "A single argument must be provided"; exit 1; }
  tmp=`mktemp` && expand "$1" > "$tmp" && mv "$tmp" "$1"
}

Mit einer kleinen Änderung können wir die gesamte expandFunktionalität durch unterstützende Argumente wiederherstellen. Es gibt einen kleinen Trick, um das letzte Argument zu erfassen, damit wir den Dateinamen der Objektdatei kennen und sie letztendlich mit der Ausgabe von überschreiben können expand. Das letzte Argument wird als referenziert ${@ -1}.

expand() {
      [[ "$#" -lt "1" ]] && { echo "At least a file name argument must be provided"; exit 1; }
      # Here we capture the last argument which is the object file name
      fname="${@: -1}"
      # The upcoming call to expand passes on all arguments including the file name
      tmp=`mktemp` && expand "$@" > "$tmp" && mv "$tmp" "$fname"
    }

Ich habe diesen Code nicht getestet und entschuldige mich daher, falls ein Syntaxfehler vorliegt, den ich nicht bemerkt habe.

Eine dieser Funktionen oder eine Version davon sollte in .bashrceiner entsprechenden Datei abgelegt werden, die beim Erstellen einer neuen Shell als Quelle verwendet wird, sodass sie sofort verfügbar ist.

Wenn Sie angeben möchten, ob die Datei „vor Ort“ aktualisiert wird oder ob die Aktualisierung an stdout gesendet wird, kann diese Funktionsvorlage so geändert werden, dass dies auf der Grundlage eines zusätzlichen Arguments erfolgt (das nicht an expand weitergegeben wird, aber ändert, wie wir expand aufrufen). Ich bin nicht sicher, ob Sie danach suchen, aber ich denke, Sie haben jetzt alle Informationen, die Sie dafür benötigen, wenn das der Fall ist.

Oder für mehr Spaß, laden Sie die GNU coreutilsQuellcodeund dassed-Quellcode, sehen Sie sich an, wie sed damit umgeht, und migrieren Sie diesen Code in Ihre neue, verbesserte Version von expand. Senden Sie diese Änderung an die Betreuer zurück, und Sie haben dies möglicherweise für alle zukünftigen „Expand“-Benutzer vereinfacht.

verwandte Informationen