Ich möchte mehrere c-Quelldateien in einem Verzeichnis kopieren und umbenennen.
Ich kann so kopieren:
$ cp *.c $OTHERDIR
Aber ich möchte allen Dateinamen ein Präfix geben:
file.c --> old#file.c
Wie kann ich das in 1 Schritt machen?
Ich möchte mehrere c-Quelldateien in einem Verzeichnis kopieren und umbenennen.
Ich kann so kopieren:
$ cp *.c $OTHERDIR
Aber ich möchte allen Dateinamen ein Präfix geben:
file.c --> old#file.c
Wie kann ich das in 1 Schritt machen?
Antworten:
eine forSchleife:
for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done
Ich füge oft die -vOption hinzu, cpdamit ich den Fortschritt verfolgen kann.
Sie können Shell Globbing verwenden:
for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done
Das for variable in GLOBFormat erweitert den Glob auf alle übereinstimmenden Dateien / Verzeichnisse (mit Ausnahme der versteckten) und iteriert über diese, wobei jede nacheinander als $variable(im obigen Beispiel $f) gespeichert wird . Der Befehl, den ich zeige, durchläuft also alle nicht versteckten Dateien, kopiert sie und fügt das Präfix hinzu.
cd /foo/bar/; for f in *coder verwenden for f in /foo/bar/*.c; do name=${f##*/} ...oder name=$(basename "$f").
Noch ein anderer Weg:
for f in $(find dir/ -type f | grep -v 'bk_'); do cp -- "$f" "$(dirname $f)/bk_$(pwgen -s 4 1)_$(basename $f)"; done
Jedes Mal, wenn Sie auf diese Weise laufen, wird dir / from geändert:
dir/foo/foo.c
dir/bar/bar.c
dir/baz/baz.c
In:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
Und dann:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/foo/bk_dV06_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/bar/bk_B68i_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
dir/baz/bk_p6P3_baz.c
Und dann...:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/foo/bk_dV06_foo.c
dir/foo/bk_2Ar8_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/bar/bk_B68i_bar.c
dir/bar/bk_wX7Z_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
dir/baz/bk_p6P3_baz.c
dir/baz/bk_fPd3_baz.c
.. und so weiter.
finddie Ausgabe . Verwenden Sie grepdiese Option nicht , um Dateinamen auszuschließen, wenn dies findalleine möglich ist.
Hier ist, wie man es bei Bedarf rekursiv machen würde:
for f in `find . -name \*.c`; do name="${f//\.\//__}"; fileName="${name//\//_}" ; echo "Copying $f as $OTHERDIR/old#$fileName"; cp -- "$f" "$OTHERDIR/$fileName"; done
finddie Ausgabe
Hier ist ein Einzeiler mit xargs, trund Globbing. Könnte einen Wert haben.
echo *.c | tr ' ' '\n' | xargs -n1 -I{} cp "{}" "PREFIX{}"
Dies gibt alle übereinstimmenden Dateien *.cals durch Leerzeichen getrennte Zeichenfolge zurück. Als nächstes werden trdie zusätzlichen Leerzeichen in Zeilenumbrüche umgewandelt ( NB hat Dateinamen nicht mit Leerzeichen ** getestet). Wird xargsdann mit jedem Dateinamen gefüllt und cpmit dem entsprechenden Namen und Präfix ausgeführt.
*.ckann für andere nützliche Globs geändert werden. Andere Präfixe im Teil xargsund cpkönnen ebenfalls verwendet werden.
(erfordert findUnterstützung -print0) Ähnlich wie oben können wir findeine durch Null getrennte Liste von Dateien ausgeben und xargsmit einem Flag optimieren , um bei Null zu trennen
find . -name '*.c' -print0 | xargs -0 -n1 -I{} cp "{}" "PREFIX{}"
for f in /foo/bar/*.c,$fwird der gesamte Pfad enthalten, stattdessen nur der Name der Datei. Wie kann ich nur den Namen der Datei erhalten?