Estoy componiendo un script para procesar 20 archivos. Todos ellos ubicados en diferentes directorios. Tengo un nombre de archivo parcial.
El directorio File1 es /data/data1directory/Sample_File1/logs/File1_Data_time.err
El directorio File2 es /data/data2directory/Sample_File2/logs/File2_Data_time.err
.....
Mi guión se ve así. (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 Al ejecutarlo, lo intenté.
./runrunrun.sh Archivo1
. runrunrun.sh Archivo1
sh runrunrun.sh Archivo1
mv: no se puede mover /data/data1directory/Sample_File1/logs/File1_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err : No existe tal archivo o directorio cp también recibió comentarios similares
¿Lo estoy haciendo correctamente?
¡Gracias!
Hablemos de cómo funcionan los comodines por un minuto.
cp *.txt foo en realidad no invoca cp con un argumento *.txt , si existe algún archivo que coincida con ese globo. En su lugar, ejecuta algo como esto:
cp a.txt b.txt c.txt fooDel mismo modo, algo como
mv *.txt *.old... posiblemente no pueda saber qué hacer, porque cuando se invoca, lo que ve es:
mv a.txt b.txt c.txt *.old o, peor aún, si ya tiene un archivo llamado z.old , verá:
mv a.txt b.txt c.txt z.oldPor lo tanto, es necesario utilizar diferentes herramientas. Considerar:
# 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 doneEsto utiliza una expansión de parámetros para eliminar el final del nombre anterior antes de agregar el nuevo nombre.
El comando de find se puede usar de manera bastante concisa en casos simples en los que desea realizar operaciones en coincidencias de nombre de archivo comodín (o más complejas). La siguiente técnica se puede memorizar... ¡casi!
Esto funciona al permitir que el comando de find ejecute otro comando en cada nombre de archivo que encuentre. Puede ejecutar este ejemplo en seco usando echo en lugar de/delante de mv .
Si quisiéramos mover todos los archivos en el directorio actual cuyo nombre comienza con 'informe', a otro directorio paralelo llamado 'informes':
find . -name "report*.*" -exec mv '{}' ../reports/ \;La cadena comodín debe estar entre comillas, el {} que marca el nombre del archivo que se 'encontró' debe estar entre comillas y el punto y coma final debe escaparse, todo debido al tratamiento de Bash/shell de esos caracteres.
Mire la página de manual para find más usos: https://linux.die.net/man/1/find
Esto es lo que uso, muy rápido para escribir y recordar.
Para copiar:
ls -1 *.txt | xargs -L1 -I{} cp {} {}.oldPara mover:
ls -1 *.txt | xargs -L1 -I{} mv {} {}.oldla explicación:
xargs(1) -L1 -I{}construir y ejecutar líneas de comando desde la entrada estándar
-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. Básicamente, con -L1 envía los argumentos uno por uno, y -I{} convierte a {} en el marcador de posición