Tengo un montón de archivos a los que me gustaría cambiarles el nombre. Sus nombres de archivo están en un formato determinado:
p1.uniquenameA#blah_a
p2.uniquenameB#blah_b
p3.uniquenameC#blah_c
p4.uniquenameD#blah_d
p5.uniquenameE#blah_e
p6.uniquenameF#blah_f
p7.uniquenameG#blah_g
p8.uniquenameH#blah_h
p9.uniquenameI#blah_i
p10.uniquenameJ#blah_j
Hay un prefijo antes de cada nombre de archivo único. En este caso, ese prefijo comienza con la letra p
y tiene un número después p
que aumenta en uno. Un punto ( .
) separa el prefijo del nombre de archivo único. Hay un sufijo después de cada nombre de archivo único que comienza con un hashtag ( #
). Me gustaría eliminar los prefijos hasta los puntos inclusive y también me gustaría eliminar los sufijos que comienzan en los hashtags inclusive. Me gustaría que los nombres de archivos resultantes fueran solo los nombres de archivos únicos entre los puntos y las etiquetas hash como esta:
uniquenameA
uniquenameB
uniquenameC
uniquenameD
uniquenameE
uniquenameF
uniquenameG
uniquenameH
uniquenameI
uniquenameJ
Soy nuevo en el mundo de las secuencias de comandos, por lo que si pudiera explicarme cómo funciona el código además de proporcionarlo, se lo agradecería mucho.
Respuesta1
Si tiene la perl
versión de rename
(a veces llamada anteriormente prename
), puede aplicar una sustitución de expresión regular:
rename -n 's/^.*?\.(.*?)#.*/$1/' *
Si no comprende las expresiones regulares (RE), vale la pena aprenderlas.
s/xx/yy/
- reemplazarxx
conyy
^
- coincidir con un inicio de línea implícito.*?
- hacer coincidir una cadena lo más corta posible decero o más caracteres de cualquier cosasujeto a que el resto del patrón coincida\.
- coincidir con un punto literal.
(el.
carácter representacualquier cosa, pero\.
es un punto literal)(
...)
haga coincidir un patrón dentro de los corchetes y asígnele un número de coincidencia 1..9; posteriormente referenciado por$1
(el segundo(
...)
sería$2
, etc.)#
- carácter literal.*
- el partido más largo que escero o más caracteres de cualquier cosa(el.
escualquier cosay los*
medios _cero o más del ítem anterior)
Elimine -n
("sin acción") cuando esté satisfecho.haríatrabajar. Reemplácelo para -v
ver qué está sucediendo realmente o simplemente omítalo para un funcionamiento silencioso.
Respuesta2
Aquí hay un awk
script que realiza la tarea:
Sólo para imprimir/depurar:
awk 'match($0,/(^[^\\.]+.)([^#]+)/,m){print "mv "$0" "m[2] }' input.txt
Haz el cambio de nombre:
awk 'match($0,/(^[^\\.]+.)([^#]+)/,m){system("mv "$0" "m[2])}' input.txt
entrada.txt
p1.uniquenameA#blah_a
p2.uniquenameB#blah_b
p3.uniquenameC#blah_c
p4.uniquenameD#blah_d
p5.uniquenameE#blah_e
p6.uniquenameF#blah_f
p7.uniquenameG#blah_g
p8.uniquenameH#blah_h
p9.uniquenameI#blah_i
p10.uniquenameJ#blah_j
producción
mv p1.uniquenameA#blah_a uniquenameA
mv p2.uniquenameB#blah_b uniquenameB
mv p3.uniquenameC#blah_c uniquenameC
mv p4.uniquenameD#blah_d uniquenameD
mv p5.uniquenameE#blah_e uniquenameE
mv p6.uniquenameF#blah_f uniquenameF
mv p7.uniquenameG#blah_g uniquenameG
mv p8.uniquenameH#blah_h uniquenameH
mv p9.uniquenameI#blah_i uniquenameI
mv p10.uniquenameJ#blah_j uniquenameJ
Respuesta3
Aquí hay una solución usandosed
for i in *
do
mv $i $( echo $i | sed 's/p[[:digit:]]*\.\([^#]*\)\#.*/\1/' )
done
El destino se crea buscando sed
un p
seguido de cualquier número de dígitos seguido de un punto. Los personajes desde la época en adelante hasta el #
personaje sonrecordadoen un registro, y el nombre completo del archivo se sustituye por elrecordadocaracteres.