podemos suponer sed
está disponible en cualquier * nix, pero no podemos estar seguros de que va a apoyar a sed -n
generar comandos mv. (NOTA: Sólo GNUsed
hace esto.)
Aun así, órdenes internas de bash y sed, que puede azotar rápidamente una función de shell para hacer esto.
sedrename() {
if [ $# -gt 1 ]; then
sed_pattern=$1
shift
for file in $(ls [email protected]); do
mv -v "$file" "$(sed $sed_pattern <<< $file)"
done
else
echo "usage: $0 sed_pattern files..."
fi
}
Uso
sedrename 's|\(.*\)\(-[0-9.]*\.pkg\)|\1\2|' *.pkg
before:
./Xft2-2.1.13.pkg
./jasper-1.900.1.pkg
./xorg-libXrandr-1.2.3.pkg
after:
./Xft2.pkg
./jasper.pkg
./xorg-libXrandr.pkg
Creación de carpetas de destino:
Desde mv
no crea automáticamente carpetas de destino que no podemos utilizando nuestra versión inicial de sedrename
.
Es un cambio bastante pequeño, por lo que sería bueno para incluir esa característica:
necesitaremos una función de utilidad, abspath
(o ruta absoluta) desde el golpe no tiene esta estructura en.
abspath() { case "$1" in
/*)printf "%s\n" "$1";;
*)printf "%s\n" "$PWD/$1";;
esac; }
una vez que tenemos que podemos generar la carpeta (s) objetivo para una sED/cambiar el nombre de modelo que incluye la nueva estructura de carpetas.
Esto asegurará que conocemos los nombres de nuestras carpetas de destino. Cuando cambiemos el nombre , tendremos que usarlo en el nombre del archivo de destino.
# generate the rename target
target="$(sed $sed_pattern <<< $file)"
# Use absolute path of the rename target to make target folder structure
mkdir -p "$(dirname $(abspath $target))"
# finally move the file to the target name/folders
mv -v "$file" "$target"
Aquí está la carpeta de scripts conscientes completo ...
sedrename() {
if [ $# -gt 1 ]; then
sed_pattern=$1
shift
for file in $(ls [email protected]); do
target="$(sed $sed_pattern <<< $file)"
mkdir -p "$(dirname $(abspath $target))"
mv -v "$file" "$target"
done
else
echo "usage: $0 sed_pattern files..."
fi
}
Por supuesto, todavía funciona cuando no tenemos carpetas de destino específica también.
Si quisiéramos poner todas las canciones en una carpeta, ./Beethoven/
podemos hacer esto:
Uso
sedrename 's|Beethoven - |Beethoven/|g' *.mp3
before:
./Beethoven - Fur Elise.mp3
./Beethoven - Moonlight Sonata.mp3
./Beethoven - Ode to Joy.mp3
./Beethoven - Rage Over the Lost Penny.mp3
after:
./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3
ronda de bonificación ...
El uso de este script para mover archivos de carpetas en una sola carpeta:
Suponiendo que quisiéramos reunir todos los archivos coincidentes, y colocarlos en la f actual mayor, podemos hacerlo:
sedrename 's|.*/||' **/*.mp3
before:
./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3
after:
./Beethoven/ # (now empty)
./Fur Elise.mp3
./Moonlight Sonata.mp3
./Ode to Joy.mp3
./Rage Over the Lost Penny.mp3
Nota sobre los patrones de expresiones regulares de sed se aplican
reglas de patrones regulares de sed en este script, estos patrones no son PCRE (Las expresiones regulares compatibles con Perl). Puede haber sed sintaxis de expresión regular extendida, usando sed -r
o sed -E
dependiendo de su plataforma.
Consulte la norma POSIX man re_format
para obtener una descripción completa de sed basic y extended regexp patterns.
Tengo la intención de utilizar esto regularmente, como una secuencia de escritura de uso de una sola vez. Cualquier sistema que voy a utilizar tendrá bash, así que no le temo a los bashisms que son bastante útiles. –
Más en general, vea también https://stackoverflow.com/questions/28725333/looping-over-pairs-of-values-in-bash – tripleee