nous travaillons sur un projet angularjs, où la sortie compilée contient de nombreuses extensions de fichiers comme js, css, woff, etc. ainsi que le hachage dynamique individuel dans le cadre du nom de fichier.
Je travaille sur un simple bash script pour rechercher les fichiers appartenant aux extensions de fichiers mentionnées et se déplacer vers un dossier dont le hachage a été supprimé par recherche de la première instance de «.».
Veuillez noter que les extensions de fichier .woff et .css doivent être conservées.
cp $files ${DST}"${files//.*}".js
1.620807da7415abaeeb47.js
cp: cannot create regular file `./dst/./src/1.620807da7415abaeeb47.js.js': No such file or directory
Code Bash: strong>
SFILES=./src/*.{js,css,voff}
cp: cannot stat `./src/*.{js,css,voff}': No such file or directory
Le code ci-dessus a 2 problèmes, Besoin d'ajouter des extensions de fichier dans la boucle for à un endroit commun, au lieu de s'exécuter pour chaque extension. Cependant, cette méthode échoue, je ne suis pas sûr que cela doive être changé.
#!/bin/bash
echo Process web binary files!
echo Processing the name change for js files!!!!!!!!!!!!!
sfidx=0;
SFILES=./src/*.js #{js,css,voff}
DST=./dst/
for files in $SFILES
do
echo $(basename $files)
cp $files ${DST}"${files//.*}".js
sfidx=$((sfidx+1))
done
echo Number of target files detected in srcdir $sfidx!!!!!!!!!!
Deuxièmement, le cp cmd échoue pour une raison ci-dessous, vous avez besoin d'aide pour déterminer la syntaxe correcte.
/src/main.1cc794c25c00388d81bb.js ==> /dst/main.js /src/polyfills.eda7b2736c9951cdce19.js ==> /dst/polyfills.js /src/runtime.a2aefc53e5f0bce023ee.js ==> /dst/runtime.js /src/styles.8f19c7d2fbe05fc53dc4.css ==> /dst/styles.css /src/1.620807da7415abaeeb47.js ==> /dst/1.js /src/2.93e8bd3b179a0199a6a3.js ==> /dst/2.js /src/some-webfont.fee66e712a8a08eef580.woff ==> /dst/some-webfont.woff /src/Web_Bd.d2138591460eab575216.woff ==> /dst/Web_Bd.woff
4 Réponses :
Votre problème est la priorité des extensions. Voici ma solution:
Process web binary files! Processing the name change for js files!!!!!!!!!!!!! copying ./src/gash.js to ./dst/gash.js copying ./src/gash.css to ./dst/gash.js copying ./src/gash.voff to ./dst/gash.js Number of target files detected in srcdir 3!!!!!!!!!!
Avec trois fichiers dans ./src tous nommés "gash", j'obtiens:
#!/bin/bash
echo Process web binary files!
echo Processing the name change for js files!!!!!!!!!!!!!
sfidx=0;
SFILES=$(echo ./src/*.{js,css,voff})
DST=./dst/
for file in $SFILES
do
new=${file##*/} # basename
new="${DST}${new%\.*}.js" # escape \ the .
echo "copying $file to $new" # sanity check
cp $file "$new"
sfidx=$((sfidx+1))
done
echo Number of target files detected in srcdir $sfidx!!!!!!!!!!
(Vous pourriez être capable de se déplacer en utilisant eval , mais cela peut être un problème de sécurité)
new = $ {file ## * /} - supprimer le plus long chaîne à gauche se terminant par / (supprimer les noms de répertoires principaux, comme basename ). Si vous vouliez utiliser le programme externe non-shell basename , alors ce serait new = $ (basename $ file) .
$ {new% \. *} - supprimer la chaîne la plus courte à droite commençant par . (supprimer l'ancienne extension de fichier)
Veuillez noter que les extensions de fichier .css et .woff doivent être conservées.
@ Murukz-userm: ce n'est pas ce que disait votre message d'origine
Voici une commande relativement simple pour le faire:
find ./src -type f \( -name \*.js -o -name \*.css -o -name \*.woff \) -print0 |
while IFS= read -r -d $'\0' line; do
dest="./dst/$(echo $(basename $line) | sed -E 's/(\..{20}\.)(js|css|woff)/\.\2/g')"
echo Copying $line to $dest
cp $line $dest
done
rechercher ./src -type f | egrep '. * \. (js | css | woff)' | tr '\ n' '\ 0' appelle trois commandes pour obtenir exactement le même résultat que find ./src -type f \ (-name \ *. js -o -name \ *. css - o -name \ *. woff \) -print0 avec une seule commande.
Réponse corrigée @Dario
Très bien :) :)
echo Traitement du changement de nom pour les fichiers js css woff !!!!!!!!!!!!! SRC =. / Src / DST =. / Dst / mfidx = 0; find $ SRC -type f (-name * .js -o -name * .css -o -name * .woff) -print0 | while IFS = lecture -r -d $ '\ 0' ligne; do local dest = "$ DST / $ (echo $ (nom de base $ line) | sed -E 's / (\ .. {20} \.) (js | css | woff) / \. \ 2 / g') "echo Copie de $ line vers $ DST cp $ line $ dest mfidx = $ ((mfidx + 1)) done echo Le nombre de fichiers js css woff déplacés est $ mfidx !!!!!!!!!! écho ""
Veuillez noter que les extensions de fichier .woff et .css doivent être conservées. J'ai essayé le code, mais j'ai obtenu l'erreur comme: ./processwhwwebbin.sh: ligne 21: local: ne peut être utilisé que dans une fonction Copie ./src/2.93e8bd3b179a0199a6a3.js vers ./dst/ cp: opérande du fichier de destination manquant après `. /src/2.93e8bd3b179a0199a6a3.js '
J'ai corrigé l'erreur dans la commande. J'ai oublié que local ne peut pas être utilisé en dehors d'une fonction.
Maintenant ça marche, merci @AidanLovelance
Une approche possible consiste à demander à la commande find de générer un script shell, puis de l'exécuter.
find $src \( -name \*.js -o -name \*.woff -o -name \*.css \) \
-printf "p=%p; f=%f; cp \$p ${dst}/\${f%%%%.*}.\${f##*.}\\n"|bash
Cela affichera les commandes shell que vous voulez exécuter. Si c'est ce que tu veux, dirigez simplement la sortie vers un shell:
find "$src" \( -name \*.js -o -name \*.woff -o -name \*.css \) \
-printf 'p="%p"; f="%f"; cp "$p" "'"${dst}"'/${f%%%%.*}.${f##*.}"\n'|bash
(ou | bash -x si vous voulez voir ce qui se passe.) p >
Si vous avez des fichiers nommés, par exemple ./src/dir1/a.xyz.js et ./src/dir2/a.uvw.js , ils finira tous les deux par ./dst/a.js , le second écrasant le premier. Pour éviter cela, vous pouvez utiliser cp -i au lieu de cp.
Si vous êtes absolument sûr qu'il n'y aura jamais d'espace ou autre des caractères étranges dans vos chemins, vous pouvez utiliser moins de guillemets (à l'horreur de certains puristes du shell)
src=./src
dst=./dst
find "$src" \( -name \*.js -o -name \*.woff -o -name \*.css \) \
-printf 'p="%p"; f="%f"; cp "$p" "'"${dst}"'/${f%%%%.*}.${f##*.}"\n'
Quelques remarques finales:
% p et % f sont développés par -printf comme chemin complet et nom de base du fichier traité. ils nous permettent d'éviter la commande basename . Malheureusement, il n'existe pas de directive de ce type pour l'extension de fichier, nous devons donc utiliser l'expansion entre accolades dans le shell pour composer le nom final.
Dans l'argument -printf , nous devons utiliser %% pour écrire un seul caractère de pourcentage. Puisque nous avons besoin de deux d'entre eux, il doit y en avoir quatre ...
$ {f %%. *} se développe dans le shell comme la valeur de $ f avec tout supprimé à partir du premier point
$ {f ## *.} se développe dans le shell comme la valeur de $ f avec tout supprimé jusqu'au dernier point (c'est-à-dire qu'il se développe à l'extension de fichier)
Veuillez noter que les extensions de fichier .woff et .css doivent être conservées
$ {## *.} est l'extension du fichier (lisez ma dernière remarque) et elle est conservée.
Notant non copié p = "./ src / 2.93e8bd3b179a0199a6a3.js"; f = "2,93e8bd3b179a0199a6a3.js"; cp "$ p" "./dst//${f%%.*}.${f##*.}"
Veuillez lire tous ma réponse. Vous avez exécuté le code qui ne fait rien d'autre qu'imprimer les commandes à donner au shell. Le code pour les exécuter se trouve dans le paragraphe suivant, avec une remarque sur la façon d'obtenir une sortie verbeuse (option -x pour le sous-shell)
Ceci est basé sur le code d'origine et est Shellcheck -clean:
#!/bin/bash
shopt -s nullglob # Make globs that match nothing expand to nothing
echo 'Process web binary files!'
echo 'Processing the name change for js, css, and woff files!!!!!!!!!!!!!'
srcfiles=( src/*.{js,css,woff} )
destdir=dst
for srcpath in "${srcfiles[@]}" ; do
filename=${srcpath##*/}
printf '%s\n' "$filename"
nohash_base=${filename%.*.*} # Remove the hash and suffix from the end
suffix=${filename##*.} # Remove everything up to the final '.'
newfilename=$nohash_base.$suffix
cp -- "$srcpath" "$destdir/$newfilename"
done
echo "Number of target files detected in srcdir ${#srcfiles[*]}!!!!!!!!!"
Veuillez noter que les extensions de fichier .woff et .css doivent être conservées.
@ Murukz-userm, le code conserve les extensions de fichier (js, css et woff). Je l'ai testé sur des fichiers avec les mêmes chemins que les exemples de la question avant de le publier.