Intercambie dos cadenas separadas por un símbolo en varios nombres de archivos de un directorio

Intercambie dos cadenas separadas por un símbolo en varios nombres de archivos de un directorio

Quiero cambiar una cadena como author - nameen los nombres de archivo de algunos libros a name - author. Lo estoy intentando

ls * | sed -r 's/(.+) - (.+).pdf/mv \2 - \1.pdf/' | sh

Tal vez sea una mezcla de Cambie dos cadenas de longitud arbitraria separadas por un símbolo yCambiar el nombre de varios archivos con sed

esto no funciona

for file in *; do mv "$file" "$(echo "$file" | sed -r 's/(.+) - (.+).pdf/\2 - \1.pdf/')"

Tampoco lo hace

rename 's/\([.]+\) - \([.]+\)\.pdf/\2 - \1\.pdf/' *

Esto funciona

rename 's/(.+) - (.+).pdf/\2 - \1.pdf/' *

Respuesta1

Prueba esto

% ls -1                                                                                                       
001-foobar.pdf
002-foobar.pdf
003-foobar.pdf

Código

% rename -n 's/([^-]+)-([^\.]+)\.pdf/$2-$1.pdf/' *.pdf                                                          
001-foobar.pdf -> foobar-001.pdf
002-foobar.pdf -> foobar-002.pdf
003-foobar.pdf -> foobar-003.pdf

Nota

(elimine el modificador -n cuando sus pruebas estén bien)

advertencia Hay otras herramientas con el mismo nombre que pueden o no ser capaces de hacer esto, así que tenga cuidado.

Si ejecuta el siguiente comando ( GNU)

$ file "$(readlink -f "$(type -p rename)")"

y tienes un resultado como

.../rename: Perl script, ASCII text executable

y que no contenga:

ELF

entonces esta parece ser la herramienta adecuada =)

De lo contrario, para convertirlo en el valor predeterminado (generalmente ya es el caso) en Debianun derivado como Ubuntu:

$ sudo update-alternatives --set rename /path/to/rename

(reemplace /path/to/renamela ruta de su perl's renamecomando.


Si no tiene este comando, busque en su administrador de paquetes para instalarlo ohazlo manualmente


Por último, pero no menos importante, esta herramienta fue escrita originalmente por Larry Wall, el padre de Perl.

Respuesta2

Supongo que los nombres de los archivos siguen el patrón author - name.pdfy que ambos authorpueden namecontener cualquier carácter válido además de -estar rodeados de espacios.

find . -type f -name '* - *.pdf' \
    -execdir sh -c 'b=${1% - *}; e=${1#* - }; mv "$1" "${e%.pdf} - $b.pdf"' sh {} \;

Esto busca todos los archivos normales en el directorio actual que tengan nombres que coincidan con el patrón * - *.pdf.

Para cada uno de estos archivos, se ejecuta una subcapa. La subcapa hace lo siguiente:

b=${1% - *}  # pick out the start of the filename
e=${1#* - }  # pick out the end of the filename

# Combine $b and $e into a new filename while removing ".pdf" from
# the end of the original filename and adding it to the end of
# the new filename instead.
mv "$1" "${e%.pdf} - $b.pdf"

Probándolo:

$ ls -l
total 0
-rw-r--r--  1 kk  wheel  0 Aug 30 11:31 arr! - Boaty McBoatface.pdf
-rw-r--r--  1 kk  wheel  0 Aug 30 11:30 hello world - bingo-night!.pdf

$ find . -type f -name '* - *.pdf' -execdir sh -c 'b=${1% - *}; e=${1#* - }; mv "$1" "${e%.pdf} - $b.pdf"' sh {} \;

$ ls -l
total 0
-rw-r--r--  1 kk  wheel  0 Aug 30 11:31 Boaty McBoatface - arr!.pdf
-rw-r--r--  1 kk  wheel  0 Aug 30 11:30 bingo-night! - hello world.pdf

Ejecutarlo nuevamente cambiaría los nombres a sus originales.

información relacionada