Frage Linux mv Datei mit langem Namen


Unter Linux benenne ich Dateien manchmal wie folgt um:

mv dir1/dir2/dir3/file.txt  dir1/dir2/dir3/file.txt.old

Beachten Sie, dass ich die Datei nur umbenennen und nicht in ein anderes Verzeichnis verschieben möchte.

Gibt es einen Befehl, mit dem ich eine Kurzversion dieses Befehls erstellen kann? Ich denke etwa so:

mv dir1/dir2/dir3/file.txt  file.txt.old

oder vielleicht sogar so etwas (um nur an den Namen anzuhängen):

mv dir1/dir2/dir3/file.txt  {}.old

Mein Ziel ist nicht, den vollständigen Pfad erneut angeben zu müssen.

Ich weiß, dass diese "Beispiele", die ich geschrieben habe, nicht funktionieren, aber es ist nur eine Idee dessen, was ich erreichen möchte.

Ich möchte nicht in das Verzeichnis einsteigen müssen.


19
2018-01-20 17:52


Ursprung


Warum wechselst du nicht in das Verzeichnis? Es ist schnell und löst Ihr Problem. - Michael Hampton♦
Ich habe es mit vielen Unterverzeichnissen von demselben Ort zu tun, es ist langsamer, wenn ich jedes Mal zu diesem Elternverzeichnis zurückkehren muss - santiago arizti
Niemand hat gesagt, dass du in ein anderes Verzeichnis wechseln musst, nur das, das du willst. - Michael Hampton♦
Beachten Sie, dass (cd dir1/dir2/dir3 && exec mv file.txt{,.old}) hat effektiv die gleiche Leistung wie der Code ohne den Subprozess, weil die exec vermeidet fork()während des externen Befehlsaufrufs, so haben Sie genau eine Gabel in beide Richtungen. - Charles Duffy


Antworten:


für eine einzelne Datei versuchen

mv dir1/dir2/dir3/file.{txt,txt.old}

bei dem die X{a,b} Konstrukt erweitern zu Xa Xb, können Sie eine Vorschau verwenden

echo dir1/dir2/dir3/file.{txt,txt.old}

um zu sehen, ob es Ihren Bedürfnissen entspricht.

Hinweis:

  1. das für mehrere Dateien

    mv dir1/dir2/dir3/file{1,2,3}.{txt,txt.old}
    

Es ist unwahrscheinlich, dass sie sich auf das ausdehnen, was Sie wollen. (Dies wird zu einer Mischung aus Datei.txt Datei1.txt.old Datei2.txt erweitert ...)

  1. {txt,txt.old} kann verkürzt werden {,.old} laut Kommentar

  2. Wenn der Verzeichnisname eindeutig ist, kann Platzhalter verwendet werden.

    mv *1/*2/d*/*.{,old}
    

für die Mehrfachnutzung von Dateien rename

rename -n s/txt/old.txt/ dir1/dir2/dir3/file*.txt 

fallen -n effektive Umbenennung haben


44
2018-01-20 18:14



Nett, ich kannte diese Art der Erweiterung nicht! Danke dir - santiago arizti
Würde mv dir1/dir2/dir3/file.txt{,.old} nicht auch arbeiten und noch kürzer sein? - Josh
@Josh Ja, es funktioniert perfekt und erfordert weniger Tastenanschläge. Ich benutze dieses Konstrukt sehr regelmäßig. - rlf
Es ist witzig, wie man die Linux-Shell jahrelang nutzen kann und immer noch neue Tricks findet - santiago arizti
Ich denke, all diese "Tricks" wären offensichtlicher, wenn ich eine formelle Ausbildung in der Bash-Sprache gehabt hätte, aber ich habe gerade genug gelernt, um miteinander auszukommen. - santiago arizti


Der Befehl rename Benennt alle übereinstimmenden Dateien um. Sein Hauptzweck besteht darin, mehrere Dateien umzubenennen. Wenn der Perl-Ausdruck jedoch nur einer Datei entspricht, wird nur diese einzelne Datei umbenannt. Für Details und Distro-spezifische Syntax lesen Sie bitte die Manpage: man rename.

Beispielverwendung: Benenne "/path/file.txt" in "/path/file.txt.old" um:

rename 's/file.txt/file.txt.old/g' /path/file.txt

Kürzere Notation (dank Shalomb):

rename 's/$/.old/' /path/file.txt
rename '$_.=".old"' /path/file.txt

Für einen Trockenlauf verwenden rename -n.

Weitere Beispiele und Details finden Sie unter https://thepcspspy.com/read/bulk-rename-files-in-ubuntu/


6
2018-01-20 18:05



cool, ich wusste von dem Umbenennungsbefehl, wusste nur nie alles was er tun konnte, danke! - santiago arizti
Leider haben verschiedene Linux-Distributionen unterschiedliche rename Befehle mit völlig anderem Verhalten. - kasperd
Für diese besondere Aufgabe des Umbenennens durch Anhängen .old zu dem Dateinamen, Es ist wahrscheinlich ein bisschen bequemer, ein zu tun rename 's/$/.old/' /path/to/file.txt oder rename '$_.=".old"' /path/to/file.txt - shalomb
@ Fabian - Ich war nicht pingelig, sondern zielte nur auf die "kürzeste Hand" für das, was ein häufig benutztes Idiom zu sein scheint, das der OP sucht :) - shalomb


Für einen einmaligen Fall, wenn ich mein aktuelles Verzeichnis nicht ändern möchte, verwende ich vielleicht eine Sub-Shell:

(cd dir1/dir2/dir3/ && mv file.txt file.txt.old)

Wegen dir cd Innerhalb der Subshell haben Sie Ihr Verzeichnis in Ihrer tatsächlichen Shell nicht geändert


4
2018-01-21 19:56



Schneller und sicherer zu verwenden && exec mv - so versuchen Sie nicht, die Umbenennung zu tun, wenn die cd versagt, und die exec verbraucht die Subshell und vermeidet so eine Leistungseinbuße. - Charles Duffy
Stimme dem zu &&  Für einen einmaligen Fall, wie ich schon sagte, würde ich mir keine Sorgen über die Kosten der Sub-Shell machen (behalte es einfach: in der Lage zu sein, sich leicht daran zu erinnern, wie es zu tun ist, ist IMO wichtiger) - Adam
Ich würde argumentieren, dass, wenn Sie sich nur an einen Weg erinnern, die Erinnerung an den effizienten Weg hilft sicherzustellen, dass Sie nicht die ineffiziente Route in Fällen gehen, in denen es tut Angelegenheit. - Charles Duffy


Ich mag @ Archemars Lösung, die Erweiterung {} zu verwenden, weil Sie sie verwenden können, wenn Sie Ihre Befehlszeile bereits gestartet haben. Hier sind einige andere Möglichkeiten für die Vollständigkeit:

F="dir1/dir2/dir3/file.txt" ; mv "$F" "$F.old"

(Anführungszeichen sind nur notwendig, wenn Sie im Namen Leerzeichen oder andere Worttrennzeichen haben)

mymv() {
    mv "$1/$2" "$1/$3"
}

mymv dir1/dir2/dir3 file.txt file.txt.old
mymv dir5/dir6/dir7 file.txt file.txt.old

Anmerkungen:

  • Dies ist Bash-Syntax, möglicherweise verwenden Sie eine andere Shell
  • mymv kann eine vernünftige Zeichenfolge sein, ich habe mymv für "my move" verwendet.
  • Die Funktionsdefinition kann in Ihr .bash_profile eingefügt werden

Noch einer:

cd dir1/dir2/dir3 ; mv file.txt file.txt.old ; cd -

aber

(cd dir1/dir2/dir3/ && exec mv file.txt file.txt.old)

(von @Adam und @CharlesDuffy) ist wohl besser, falls die CD ausfällt.


4
2018-01-21 14:55



Benutze es nicht mmvEs gibt bereits ein Programm, das so heißt. - glglgl
@glglgl Fertig :) - Law29


Wenn Sie das Unterverzeichnis eingeben wollen, um das zu verkürzen mv Befehl, aber wollen Sie später zum aktuellen Verzeichnis zurückkehren, gibt es zwei Möglichkeiten, dies zu tun. Einer ist es, den cd und mv in einer Subshell (wie bereits vorgeschlagen).

Das andere ist zu benutzen pushd und popd Verzeichnisse wechseln:

pushd dir1/dir2/dir3/; mv file.txt file.txt.old; popd

Daspushd Befehl ist wie cd, außer dass es zuerst den Namen des aktuellen Verzeichnisses auf einen Stapel verschiebt. popd Entfernt den obersten Namen aus dem Stapel und wechselt in dieses Verzeichnis.


2
2018-01-22 04:53



pushd und popd sind Erweiterungen, die für die interaktive Verwendung gedacht sind - POSIX listet sie explizit als "Ergebnisse sind nicht spezifiziert" auf, und eine Shell, die zum Ausführen von Skripten (dh auf einer minimalen eingebetteten Umgebung) gebaut wurde, muss sie nicht unterstützen. - Charles Duffy


Ich würde es einfach tun

cd dir1/dir2/dir3/
mv file.txt file.txt.old
cd ~- # go to the most recent directory

2
2018-01-22 13:05





Die Lösung beinhaltet: mv something{.txt,.txt.old} benutzen einen "Bashismus". Wenn Sie eine portablere Methode verwenden möchten, verwenden Sie allgemeine Variablenmanipulationen:

# rename all files "file*.txt" of directory /dir1/dir2/dir3 into file*.txt.old:
for f in dir1/dir2/dir3/file*.txt ; do
  mv "$f" "${f/.txt/.txt.old}"  # note there are no terminating "/"
done


# "${var/A/B}" is the content of var with the first occurence of "A" replaced by "B"

0
2018-01-23 10:14



Sehen pubs.opengroup.org/onlinepubs/009695399/utilities/... für die entsprechende POSIX-Spezifikation - ${var/text/replacement} ist ein Bashismus selbst. - Charles Duffy
@CharlesDuffy oh ... Du machst mich traurig :( - Olivier Dulac