Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Die Verwendung von sed für die xargs-Variable funktioniert nicht innerhalb der Shell-Erweiterung

Lösung mit sed allein

sed selbst ist in der Lage, sowohl die unmodifizierte als auch die modifizierte Zeile zu erzeugen:

$ echo "redis::staging::key" | sed 's/^/RENAME /; p; s/staging/development/g'
RENAME redis::staging::key
RENAME redis::development::key

Oben fügt sed zuerst den RENAME-String am Anfang der Zeile hinzu. Dann das p Der Befehl weist sed an, die Zeile so zu drucken, wie sie zu diesem Zeitpunkt ist (mit "staging" noch darin). Die nächste Ersetzung fügt "Entwicklung" ein und dann wird diese Version auch gedruckt.

Aktualisierung: Angenommen, wir wollen die Ausgabe in einer Zeile:

$ echo "redis::staging::key" | sed 's/.*/RENAME & &/; s/staging/development/2'
RENAME redis::staging::key redis::development::key

Die ersten s Der obige Befehl fügt RENAME am Anfang hinzu und verdoppelt dann die Zeile. Die zweite ersetzt das zweite Vorkommen von Staging durch Entwicklung.

Warum hat die xargs-Version die Ersetzung nicht vorgenommen?

xargs -I {} echo "RENAME {} $(echo {} | sed 's/staging/development/g')"

Bevor xargs ausgeführt wird, verarbeitet bash die Zeichenfolgen. Insbesondere sieht es $(echo {} | sed 's/staging/development/g') und es führt es aus ("Befehlsersetzung") und erhält das Ergebnis {} . Wenn xargs also endlich ausgeführt wird, sieht es den Befehl:

xargs -I {} echo "RENAME {} {}"

Folglich ist die Datei s/staging/development/g Ersetzung wird nie vorgenommen.

Xargs und Shell in der richtigen Reihenfolge zusammenarbeiten lassen

Dafür gibt es eine Lösung:

$ echo "redis::staging::key" | xargs -I {} sh -c 'echo RENAME {} $(echo {} | sed 's/staging/development/g')'
RENAME redis::staging::key redis::development::key

Das Obige setzt die Bash-Befehle in einfache Anführungszeichen und übergibt sie als Argumente an sh . Auf diese Weise wird der String nicht von der Shell verarbeitet, bis xargs die Ersetzungen vorgenommen hat.