git renommer de nombreux fichiers et dossiers
Je suis en train de renommer de nombreux fichiers dans mon dossier de candidature et doivent être en mesure de faire un changement de nom dans tous les sous-répertoires de la racine d'application dans git (c'est à dire git mv %filenamematch% %de remplacement%), qui ne remplace le texte correspondant. Je ne suis pas bon avec les scripts bash si.
mise à jour: il serait bon qu'il s'également renommé répertoires qui correspondent à autant!
- Avez-vous un exemple? Ce '%filenamematch%' aime; est-il toujours au début ou à la fin ou au milieu ou quoi? Quel est le %de remplacement% de ressembler?
- Il pourrait personne.rb ou lookitisa_person_here.html. Dans les deux cas, la personne doit être adapté et modifié par rapport à quelque chose d'autre. Il doit également être sensible à la casse
Vous devez vous connecter pour publier un commentaire.
Cela devrait faire l'affaire:
De suivre ce que c'est fait, vous aurez besoin de comprendre la tuyauterie avec des "|" et la substitution de commande avec "$(...)". Ces puissants shell constructions de nous permettre de combiner plusieurs commandes pour obtenir le résultat dont nous avons besoin. Voir Les Pipelines et La Substitution De Commande.
Voici ce qu'il se passe dans ce one-liner:
git ls-files
: Ce produit une liste de fichiers dans le dépôt Git. C'est similaire à ce que vous pourriez obtenir à partir dels
, sauf qu'il n'affiche Git fichiers de projet. A partir de cette liste s'assure que rien dans votre .git/répertoire obtient touché.| grep %filenamematch%
: Nous prenons la liste degit ls-files
et le tuyau à travers grep pour filtrer uniquement les noms de fichiers contenant le mot ou le modèle que nous recherchons.| sed -e 's/\(%filenamematch%[^/]*\).*/\1/'
: Nous avons tuyau de ces matchs par sed (l'éditeur de flux), l'exécution (-e) sed s (suppléant) commande pour couper tout /et les autres caractères d'après notre répertoire correspondant (si il arrive à être un).| uniq
: Dans le cas où le match est un répertoire, maintenant que nous avons coupé contenus des répertoires et des fichiers, il peut y avoir plusieurs lignes correspondants. Nous utilisons uniq pour tous les faire en une seule ligne.for file in ...
: La coque "pour la" commande va itérer sur tous les éléments (nom de fichier) dans la liste. Chaque nom de fichier, à son tour, il assigne à la variable "$fichier", puis exécute la commande après le point-virgule (;).sed -e 's/%filenamematch%/%replacement%/'
: Nous utilisons echo à pipe de chaque nom de fichier par le biais de sed, à l'aide de la commande de substitution à nouveau, cette fois pour effectuer notre modèle de remplacement sur le nom de fichier.git mv
: Nous utilisons cette commande git à mv le fichier existant ($fichier) pour le nouveau nom de fichier (celui modifié par sed).Une façon de comprendre mieux ce serait d'observer chacune de ces étapes dans l'isolement. Pour ce faire, exécutez les commandes ci-dessous dans votre coquille, et observez le résultat. Tous ces éléments sont non-destructive, seule la production de listes pour votre observation:
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
, qui sera probablement échouer si le répertoire cible n'existe pas. Pour remédier à cela, on peut ajouter un peu de logique pour les schémas nous recherchons, pour s'assurer de la correspondance de chaîne n'a pas de barres obliques après elle.for file in $(git ls-files | grep '%filenamematch%[^/]*$); git mv $file $(echo $file | sed -e 's/%filenamematch%/%replacement%[^/]*$/')
Cependant, j'aurais besoin d'un test pour s'assurer que je suis en utilisant grep et sed regex de la syntaxe correctement. Ils ne sont pas toujours exactement le même que ce que je suis habitué.git mv -f
ne sera pas.git mv [directory]
œuvres dans mes tests. Nous avons juste besoin de le couper à l'annuaire pour faire ce travail.sed
à tous:do git mv $file ${file//old/new}
. Voir: mywiki.wooledge.org/BashFAQ/100do %git mv ....%; done
pour le faire fonctionner comme décrit dans le cyberciti.biz/faq/linux-unix-bash-de-boucle-une ligne de commandebash: syntax error near unexpected token 'git'
Renommer les fichiers avec une expression régulière à l'aide de la commande
rename
:Puis enregistrer les modifications avec Git en ajoutant de nouveaux fichiers et de supprimer l'ancienne:
Dans les plus récentes versions de Git, vous pouvez utiliser le
--all
drapeau à la place:git mv
ing un fichier? L'histoire est-elle préservée?git mv
est toujours la même quegit rm
etgit add
ensemble, Git ne pas stocker des métadonnées supplémentaires pour un déménagement de la façon dont d'autres systèmes de contrôle de version faire.rename old new *
où la première occurrence denew
dans chaque nom de fichier (*
) est remplacé parold
.--all
drapeau. Je pense que c'est le meilleur moyen pour ce faire.rename
déjà fournit une méthode propre pour renommer plusieurs fichiers. Je cherchais quelque chose comme ungit rename
au lieu degit mv
, et ce n'est effectivement le même travail en utilisantrename
suivie par un simplegit add --all
. De loin la meilleure solution ici.La fin de la partie, mais, cela devrait fonctionner dans BASH (pour les fichiers et les répertoires, mais je préfère être prudent au sujet de répertoires):
*foo*
, et/foo/bar
foo=avant de la barre=après c'est mon hypothèsesh: 1: Bad substitution
sur Ubuntu 14.04, à moins que j'ai remplacésh
avecbash
, voir ici.${file/foo/bar}
la "shell paramètre d'extension" de la technique?git mv
à l'intérieur d'une boucle shell?Quel est le but de git-mv?
(En supposant que vous êtes sur une plate-forme, avec une coquille!)
Bâtiment sur la réponse par @jonathan-camenish:
Voici un exemple plus (en bash ou similaire)
voir aussi: Ad Hoc Sur L'Analyse Des Données À Partir De La Ligne De Commande Unix
mv
, utilisezgit mv
. Si vous avez besoin de plus de clarté, de mettre à jour votre question avec des exemples de renomme.Cela a bien fonctionné pour mon cas d'utilisation:
Explication:
ls folder*/*.css
- Utilisels
pour obtenir une liste de tous les répertoires avec les fichiers CSS qui correspondent le glob modèle. (Les répertoires commençant parfolder
et contenant les fichiers avec.css
extensions)while read line
- Lecture à la sortie de lals
de ligne de commande-en-lignedo git mv -- $line ${line%.css}.css
- Exécutergit mv
sur la ligne-par-ligne de sortie ($line
variable contient chaque ligne), tout en respectant le début de chaque nom de fichier et à l'exclusion de la.css
extension (avec${line%
et l'ajout d'un nouveau.scss
extension (--
est utilisé pour éviter toute ambiguïté entre les noms de fichiers et les drapeaux)Code ci-dessous peut être utilisé pour un "dry run" (ne sera pas réellement exécuter
git mv
):J'ai résolu ce problème par moi-même en utilisant
https://github.com/75lb/renamer - a parfaitement fonctionné 🙂
N'est pas explicitement de faire une
git mv
mais git semble traiter avec les résultats parfaitement de toute façon.Quand j'ai suivi toutes les étapes de la réponse sommet, je me suis coincé à l'étape finale, quand ma console a répondu avec
for pipe quote>
Si quelqu'un peut expliquer ce que j'apprécierais!
)
ou`
caractèreJe suis généralement à l'aide de NetBeans pour faire ce genre de choses parce que j'ai éviter la ligne de commande quand il y a un moyen plus facile. NetBeans a un certain appui pour git, et vous pouvez l'utiliser sur d'arbitraire répertoire/fichier via l'onglet "Favoris".