git umbenennen vieler Dateien und Ordner
Ich versuche zum umbenennen von vielen Dateien in meiner Anwendung und müssen in der Lage sein zu tun, ein umbenennen in alle Unterverzeichnisse von der app root durch git (d.h. git mv %filenamematch% %Ersatz%), die ersetzt nur den passenden text. Ich bin nicht gut mit der bash-scripting-obwohl.
update: gut wäre es, wenn auch umbenannte Verzeichnisse, die übereinstimmen, wie gut!
- Haben Sie ein Beispiel? Was '%filenamematch%' mag, ist es immer am Anfang oder Ende oder in der Mitte oder was? Was bedeutet der %Ersatz% Aussehen?
- Es könnte person.rb oder lookitisa_person_here.html. In beiden Fällen muss die person abgestimmt werden und geändert, um etwas anderes. Es sollte auch groß-und Kleinschreibung werden
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies sollte den trick tun:
Zu Folgen, was diese tun, werden Sie brauchen, um zu verstehen, Rohrleitungen mit "|" und die befehlsersetzung mit "$(...)". Diese leistungsfähige shell-Konstrukte, die es uns ermöglichen, kombinieren mehrere Befehle um das Ergebnis zu erhalten, die wir brauchen. Sehen Rohrleitungen und Kommando-Substitution.
Hier ist was Los in diesem one-liner:
git ls-files
: Dies erzeugt eine Liste der Dateien im Git-repository. Es ist ähnlich zu dem, was Sie bekommen konnte ausls
, außer es gibt nur Git-Projekt-Dateien. Ausgehend von dieser Liste sorgt dafür, dass nichts in Ihr .git/- Verzeichnis wird berührt.| grep %filenamematch%
: Wir nehmen die Liste vongit ls-files
und Rohr es durch grep filtern Sie es nach unten, um nur die Dateinamen, die das Wort oder Muster, die wir suchen.| sed -e 's/\(%filenamematch%[^/]*\).*/\1/'
: Wir Rohr diese Spiele durch sed (stream-editor), die Ausführung (-e) sed s (substitute) Befehl zum abschneiden /und das nachfolgende Zeichen, die nach unserer übereinstimmenden Verzeichnisses (wenn es passiert zu sein).| uniq
: In Fällen, wo das Spiel in ein Verzeichnis, jetzt haben wir abgehackt enthaltenen Verzeichnisse und Dateien, es könnte viele übereinstimmende Zeilen. Wir verwenden uniq, um Sie alle in eine Zeile.for file in ...
: Die shell "für" - Befehl iteriert durch alle Elemente (Dateinamen) in der Liste. Jeder Dateiname wiederum, so weist es der Variablen "$Datei" und dann führt den Befehl nach dem Strichpunkt (;).sed -e 's/%filenamematch%/%replacement%/'
: Wir verwenden echo Rohre, jedes mit dem Namen durch die sed, mit Hilfe der ersetzen-Befehl wieder-dieses mal, um unseren Muster-Ersatz auf den Dateinamen.git mv
: Wir verwenden diese git Befehl mv die vorhandene Datei ($Datei) auf den neuen Dateinamen (die man verändert, indem Sie sed).Einen Weg, um diese besser zu verstehen, wäre zu beobachten, jeden dieser Schritte in die isolation. Zu tun, führen Sie die folgenden Befehle in der shell, und beobachten Sie die Ausgabe. All diese sind nicht-destruktiv, nur die Listen für Ihre Beobachtung:
git ls-files
git ls-files | grep %filenamematch%
git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/'
git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | uniq
for file in $(git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | uniq); echo $file
for file in $(git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | uniq); echo $file | sed -e 's/%filenamematch%/%replacement%/'
git mv path/person/file.rb path/alien/file.rb
, der wird vermutlich fehlschlagen, wenn das Zielverzeichnis nicht vorhanden ist. Um das zu beheben, wir können hinzufügen, ein wenig Logik, um die Muster, die wir suchen, um sicherzustellen, die abgestimmt Zeichenfolge hat keine Schrägstriche nach.for file in $(git ls-files | grep '%filenamematch%[^/]*$); git mv $file $(echo $file | sed -e 's/%filenamematch%/%replacement%[^/]*$/')
Allerdings würde ich testen müssen, um sicherzustellen, dass ich mit grep und sed-regex-syntax richtig. Sie sind nicht immer genau das gleiche wie das, was ich gewohnt bin.git mv -f
nicht.git mv [directory]
funktioniert in meinen tests. Wir müssen nur schneiden Sie es nach unten, um das Verzeichnis zu machen, die Arbeit.sed
an alle:do git mv $file ${file//old/new}
. Siehe: mywiki.wooledge.org/BashFAQ/100do %git mv ....%; done
um es wie beschrieben unter cyberciti.biz/faq/linux-unix-bash-for-Schleife-eine-Zeile-Befehlbash: syntax error near unexpected token 'git'
Benennen Sie die Dateien mit einem regulären Ausdruck, mit dem Befehl
rename
:Dann registrieren Sie die änderungen mit Git durch das hinzufügen der neuen Dateien und die alten zu löschen:
In neueren Versionen von Git können Sie die
--all
fahne statt:git mv
ing Datei? Ist die Geschichte erhalten?git mv
ist immer der gleiche wiegit rm
undgit add
zusammen, Git speichert keine zusätzliche Metadaten, die moves der anderen version-control-Systeme benötigen.rename old new *
wo das erste vorkommen vonnew
in jedem Dateinamen (*
) ist ersetzt mitold
.--all
Flagge. Ich denke, das ist der sauberste Weg, dies zu tun.rename
bereits bietet eine saubere Art und Weise zu benennen mehrere Dateien. Ich war auf der Suche nach so etwas wie einegit rename
stattgit mv
, und dies ist effektiv der gleiche Auftrag mithilferename
gefolgt von einem einfachengit add --all
. Einfach hier die beste Lösung.Spät, um die Partei aber sollte diese Arbeit in der BASH (für Dateien und Verzeichnisse, aber ich würde vorsichtig sein, bezüglich der Verzeichnisse):
*foo*
, und/foo/bar
foo=bar vor=nach ist meine Vermutungsh: 1: Bad substitution
auf Ubuntu 14.04, es sei denn, ich ersetztesh
mitbash
finden Sie unter hier.${file/foo/bar}
"shell parameter expansion" - Technik?git mv
in einem shell-Schleife?Was ist der Sinn von git-mv?
(Vorausgesetzt, Sie sind auf einer Plattform mit einer vernünftigen shell!)
Gebäude auf die Antwort von @jonathan-camenish:
Hier ist ein Beispiel mehr (in der bash oder ähnlich)
siehe auch: Ad-Hoc-Analyse Der Daten Aus Der Unix-Befehlszeile
mv
verwendengit mv
. Wenn Sie brauchen mehr Klarheit, aktualisieren Sie Ihre Frage mit ein paar Beispiel benennt.Dies funktionierte gut für meinen Anwendungsfall:
Erklärung:
ls folder*/*.css
- Verwendetls
um eine Liste aller Verzeichnisse, die mit CSS-Dateien, die mit dem glob-pattern. (Verzeichnisse beginnend mitfolder
und die Dateien enthalten, die mit.css
Erweiterungen)while read line
- Zu Lesen in der Ausgabe vonls
Befehl line-by-linedo git mv -- $line ${line%.css}.css
- Ausführengit mv
auf den line-by-line-Ausgang ($line
variable enthält jede Zeile), während passend zu den Anfang jedes Dateinamens und ohne die.css
Erweiterung (mit${line%
und das hinzufügen eines neuen.scss
Erweiterung (--
wird verwendet, um Mehrdeutigkeit zu vermeiden, die zwischen Dateinamen und Flaggen)Folgende Code kann verwendet werden für einen "dry run" (nicht tatsächlich ausführen
git mv
):Ich löste das für mich durch die Verwendung von
https://github.com/75lb/renamer - funktioniert perfekt 🙂
Nicht explizit tun
git mv
aber git schien befassen sich mit den Ergebnissen perfekt sowieso.Wenn ich folgte alle Schritte in der oberen Antwort, die ich bekam, steckte der Letzte Schritt, wenn meine Konsole reagierte mit
for pipe quote>
Wenn jemand erklären kann, ich würde es zu schätzen wissen!
)
oder`
CharakterNormalerweise bin ich mit NetBeans zu tun, diese Art von Zeug, weil ich vermeiden Sie den Befehl Linie, wenn es ein leichter Weg. NetBeans hat einige Unterstützung für git, und Sie können es verwenden, auf beliebigen Verzeichnis/Datei über die "Favoriten" - tab.