Wie ersetze ich „$0“, speichere aber den alten Wert?

Wie ersetze ich „$0“, speichere aber den alten Wert?

Ich versuche, alle Dateien, die mit einem „m“ beginnen, so umzubenennen, dass sie denselben Namen haben, jedoch das erste Zeichen (oder in diesem Fall „m“) entfernt wird.

Meine Strategie ist:

  1. Alle Dateien auflisten, mitls
  2. Filtern Sie nach den gewünschten, mitegrep
  3. Generieren Sie die Zeichenfolge, die ich nicht möchte, neben der Zeichenfolge, die ich möchte, getrennt durch ein Leerzeichen, awkbeispielsweise mitmfoo foo
  4. Einspeisen xargsinmv mfoo foo

Einige Fragen:

  • Ist das eine gute Strategie?
  • Was ist besser?

Ich stecke bei Schritt 3 fest. Unten sehen Sie, wie ich das Problem angegangen bin.

Ich arbeite in folgendem Verzeichnis:

$ find .
.
./cat
./mbar
./mbaz
./mfoo

Ich kann schnell 1-2 bekommen:

$ ls | egrep '^m'
mbar
mbaz
mfoo

Schritt 3 ist schwieriger. Ich gsubhabe früher die zweite gewünschte Zeichenfolge generiert, bin mir aber nicht sicher, wie ich sie „mit dem Originalwert, getrennt durch ein Leerzeichen, zusammenfügen“ kann:

$ ls | egrep '^m' | awk '{ gsub(/^./, ""); print }'
bar
baz
foo

Schritt 4 ergibt für mich Sinn, obwohl ich nicht sicher bin, wie ich Schritt 3 abschließen soll, also kann ich ihn noch nicht abschließen. Unten ist ein Beispiel, wie es meiner Meinung nach funktionieren sollte:

$ echo mfoo foo | xargs mv
$ find .
.
./cat
./foo
./mbar
./mbaz

Ich glaube, ich bin nah dran. Ich muss nur noch herausfinden, wie ich den alten Wert speichere und ihn neben dem gsubed-Wert ausdrucke. Ich habe das folgende kleine Beispiel ausprobiert, aber es funktioniert nicht:

$ echo mfoo | awk '
pipe quote> { old = $0 }
pipe quote> { new = gsub(/^./, "") }
pipe quote> { print $old " " $new }'
awk: illegal field $(mfoo), name "old"
 input record number 1, file
 source line number 4
  • Wie kann ich eine Ersetzung vornehmen, $0aber den alten Wert beibehalten?
  • Warum erhalte ich diesen Fehler?

Antwort1

Dies sollte den gesamten Vorgang abwickeln:

for file in m*; do mv "${file}" "${file#m}"; done

Bevor Sie das ausführen, überprüfen Sie die Dinge zunächst mit

for file in m*; do echo mv "${file}" "${file#m}"; done

Dabei wird der m*Glob für die Schritte 1 und 2 verwendet, dann ${file#m}(wodurch „m“ am Anfang entfernt wird ${file}) für Schritt 3 und schließlich eine Schleife für Schritt 4.

Um Ihre AWK-Frage zu beantworten, könnten Sie folgendermaßen vorgehen:

echo mfoo | awk '{ print $0, substr($0, 2) }'

AWK-Variablen verwenden nicht $, das ist nur für Felder; daher kommt Ihr Fehler: AWK versteht $oldals „den Wert des Felds, nummeriert nach dem Wert von old“. Es ist auch leichter zu lesen, wenn Sie Ihre Befehle in einem einzigen Block platzieren (vorausgesetzt, sie haben das gleiche Muster). Das Korrigieren Ihres Skripts ergibt

echo mfoo | awk '{ old = $0; gsub(/^./, ""); print old, $0 }'

Antwort2

ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); $0 = x " " $0 }1' | xargs -l -t mv

Posix-lyDie Implementierung erfolgt über die -LOption xargs:

ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); $0 = x " " $0 }1' | xargs -L 1 -t mv

ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); print x, $0 }' | xargs -L 1 -t mv

Basierend woraufich antworteteAls Antwort auf Ihre frühere Frage zu xargskönnen wir das Gelernte in diesem Beispiel gut nutzen.

Ich habe Ihren awkCode leicht modifiziert: Er behält die ursprüngliche Zeile ( $0) bei, da die gsubFunktion sie überschreiben wird. Dann fügen wir das Alte und das Neue zusammen, um die Zeile zu erhalten, die wir senden möchten, xargsdie dann mit den richtigen Argumenten aufgerufen wird mv, um die Umbenennung durchzuführen.

Antwort3

Eine bessere Strategie ist die Verwendung des renameBefehls.

Beachten Sie, dass die genaue Syntax dieser Befehle distributionsspezifisch ist. Konsultieren Sie die manSeite Ihrer jeweiligen Distributionsversion. Unter Ubuntu beispielsweise, das eine Perl-Implementierung von hat rename, können Sie einen regulären Ausdruck verwenden:

rename -nono 's/^m//' m*

Hinweis: Entfernen Sie das -nonoFlag, um die Umbenennung tatsächlich durchzuführen.

verwandte Informationen