Je compose un script pour traiter 20 fichiers. Tous situés dans des répertoires différents. J'ai un nom de fichier partiel.
Le répertoire File1 est /data/data1directory/Sample_File1/logs/File1_Data_time.err
Le répertoire File2 est /data/data2directory/Sample_File2/logs/File2_Data_time.err
.....
Mon script ressemble à ceci. (runrunrun.sh)
#!/bin/bash
INPUT=$1
mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
sh /data/*/Sample_*/scripts/*_orig.sh
En l'exécutant, j'ai essayé.
./ runrunrun.sh File1
. runrunrun.sh File1
sh runrunrun.sh File1
mv: ne peut pas bouger /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
: Aucun fichier ou répertoire de ce type n'a également reçu des commentaires similaires
Suis-je en train de le faire correctement?
Merci!
Parlons du fonctionnement des caractères génériques pendant une minute.
cp *.txt foo
n'invoque pas réellement cp
avec un argument *.txt
, s'il existe des fichiers correspondant à ce glob. Au lieu de cela, il exécute quelque chose comme ceci:
cp a.txt b.txt c.txt foo
De même, quelque chose comme
mv *.txt *.old
... ne peut pas savoir quoi faire, car lorsqu'il est invoqué, ce qu'il voit est:
mv a.txt b.txt c.txt *.old
ou, pire, si vous avez déjà un fichier nommé z.old
, il verra:
mv a.txt b.txt c.txt z.old
Ainsi, vous devez utiliser différents outils. Considérer:
# REPLACES: mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
for f in /data/*/Sample_*/logs/*_Data_time.err; do
mv "$f" "${f%_Data_time.err}_Data_time_orig.err"
done
# REPLACES: cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*.sh; do
cp "$f" "${f%.sh}_orig.sh"
done
# REPLACES: sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*_orig.sh; do
if [[ -e "$f" ]]; then
# honor the script's Shebang and let it choose an interpreter to use
"$f"
else
# script is not executable, assume POSIX sh (not bash, ksh, etc)
sh "$f"
fi
done
Cela utilise un expansion des paramètres pour supprimer l'extrémité arrière de l'ancien nom avant d'ajouter le nouveau nom.
La commande find
peut être utilisée de manière assez concise dans les cas simples où vous souhaitez effectuer des opérations sur des correspondances de nom de fichier génériques (ou plus complexes). La technique ci-dessous peut être mémorisée ... presque!
Cela fonctionne en laissant la commande find
exécuter une autre commande sur chaque nom de fichier trouvé. Vous pouvez exécuter cet exemple à sec en utilisant echo
au lieu de mv
.
Si nous voulions déplacer tous les fichiers du répertoire courant avec le nom commençant par 'report', vers un autre répertoire parallèle appelé 'reports':
find . -name "report*.*" -exec mv '{}' ../reports/ \;
La chaîne générique doit être entre guillemets, le {} marquant le nom de fichier qui a été 'trouvé' doit être entre guillemets et le point-virgule final doit être échappé - tout cela en raison du traitement Bash/Shell de ces caractères.
Regardez la page de manuel pour find
pour plus d'utilisations: https://linux.die.net/man/1/find
C'est ce que j'utilise, très rapide à écrire et à mémoriser
Pour copier:
ls -1 *.txt | xargs -L1 -I{} cp {} {}.old
Pour se déplacer:
ls -1 *.txt | xargs -L1 -I{} mv {} {}.old
l'explication:
xargs(1) -L1 -I{}
construire et exécuter des lignes de commande à partir de l'entrée standard
-L max-lines
Use at most max-lines nonblank input lines per command line. Trailing blanks cause an input line
to be logically continued on the next input line. Implies -x.
-I replace-str
Replace occurrences of replace-str in the initial-arguments with names read from standard input.
Also, unquoted blanks do not terminate input items; instead the separator is the newline
character. Implies -x and -L 1.
Fondamentalement avec -L1
il envoie les arguments par un, et -I{}
fait du {}
le espace réservé
Essaye ça:
Modifiez-les:
zc_cd_delim_01.csv
zc_cd_delim_04.csv
dans ceux-ci:
zc_cd_delim_113_01.csv
zc_cd_delim_113_04.csv
ligne de commande:
for f in zc_cd_delim_??.csv; do var1=${f%%??.*};
mv $f "${var1}113_${f#$var1}";
done