shell renomeia nomes de arquivos com caracteres não imprimíveis

1

Estou tentando encontrar uma maneira de renomear em lote nomes de arquivos que originalmente contenham caracteres japoneses, que não podem ser impressos em meu shell. Há claramente algo que estou perdendo aqui para entender como funciona o regex, neste caso de uso ,

Quando executo ls , tenho isto:

AIR?t?H?[????002.jpg
AIR?t?H?[????009.jpg
AIR?t?H?[????075.jpg

E ls -ldb * me dê isso:

AIR2t2H4[2327002.jpg
AIR2t2H4[2327009.jpg
AIR2t2H4[2327075.jpg

Basicamente, quero corresponder e substituir tudo entre AIR e [0-9] *

Atualmente estou vendo algo assim:

find AIR*.jpg -type f -exec sed -ri 's/(?<=AIR)(.*?)([0-9]*)/test/' {} +

Mas recebo este erro:

sed: -e expression #1, char 31: Invalid preceding regular expression

Eu também tentei usar

echo AIR�t�H�\[����002.jpg | sed -r 's/AIR([^[:print:]\t\r])*/toto/g'

Mas renomeia AIR em vez do grupo "caractere especial"

toto�t�H�[����002.jpg

e

echo AIR�t�H�\[����002.jpg | sed -r 's/AIR([^[:print:]\t\r])*/toto/g'

retorna

sed: -e expression #1, char 33: invalid reference on 's' command's RHS

Também tr parece que pode ser uma opção, mas eu não tenho apenas caracteres especiais nos meus dois grupos AIR e [0-9] * então aqui é o que eu tenho:

echo AIR�t�H�\[����002.jpg | tr -c '[:print:]\t\r\n'test '[ *]'

retorna:

AIR t H [ 002.jpg

    
por Matthieu Ducorps 22.03.2017 / 08:22

1 resposta

4

sed substitution procura instâncias (todas as instâncias desde que você está usando g ) correspondentes ao primeiro argumento e substitui a correspondência completa pelo segundo argumento. Então, se você incluir “AIR” no primeiro argumento, ele será substituído - você precisa incluí-lo no segundo argumento se quiser mantê-lo. Quando sed reclama de uma referência inválida, isso significa que você não definiu um grupo correspondente no primeiro argumento (usando \( e \) ou ( e ) desde que você tenha especificado -r ).

Como você está procurando por "AIR" seguido por qualquer caractere seguido por dígitos, sugiro o seguinte:

sed -r 's/AIR([^[:digit:]]*)([[:digit:]]+).jpg/AIRtest.jpg/g'

Isso substitui "AIR" por "AIR", qualquer non-digits com "test" e mantém todos os dígitos depois disso. Se você não precisar processar os caracteres entre "AIR" e os dígitos, poderá ignorá-los:

sed -r 's/AIR[^[:digit:]]*([[:digit:]]+).jpg/AIRtest.jpg/g'

Se você tiver o Perl rename , poderá transpô-lo para renomear seus arquivos:

rename 's/AIR[^[:digit:]]*([[:digit:]]+).jpg/AIRtest.jpg/g' AIR*.jpg

ou

rename 's/AIR[^[:digit:]]*([[:digit:]]+).jpg/AIRtest$1.jpg/g' AIR*.jpg

( rename prefere $ para referências de grupos).

    
por 22.03.2017 / 08:58