Existe um comando linux como mv mas com regex?

37

Por exemplo, eu quero mv (.*?).sql $1.php ,

existe um comando que me permite especificar padrões de renomeação?

    
por JoshRibs 13.11.2009 / 19:33

5 respostas

32

Como outros já mencionaram, rename é bom nisso, mas leia a man page ( man rename ) antes de tentar. Existem pelo menos duas ferramentas completamente diferentes, chamadas rename e qual delas você terá, dependendo da sua distribuição. Chamá-los incorretamente pode ser perigoso.

Aqui está a página man para a versão baseada em perl de Larry Wall que acompanha o Ubuntu . Você dá uma expressão perl como rename 's/\.sql$/.php/' *.sql

Aqui está a página man para a renomeação que vem com as distribuições mais antigas da Red Hat e do CentOS. Uso é simples substituição de string como rename .sql .php *.sql

Você também pode usar um one-liner bash para processar cada arquivo, um de cada vez:

$ for f in *.sql; do mv -i "$f" "${f%%.*}.php"; done
    
por 13.11.2009 / 21:25
10

rename(1) , que não usa expressões regulares, mas pode resolver seu problema:

rename .sql .php *.sql

Há também mmv(1) , mas não estou familiarizado com o funcionamento dele.

    
por 13.11.2009 / 19:36
5

G'day

Você também pode tentar entrar

for i in $(\ls -d *.sql)
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

Ou para usar o regex, mude ligeiramente para

for i in $(\ls -d | egrep -e '.*\.sql')
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

para um pouco de diversão na codificação de shell. (-:

    
por 13.11.2009 / 19:45
1

Instale mmv e faça o seguinte:

mmv "*.sql" "#1.php"
    
por 23.08.2013 / 21:12
1

Sendo um canalizador, gosto de cachimbos:)

Nota: essa resposta é detalhada - como uma novidade, eu agradeço quando alguém que sabe dedica seu tempo para explicar, então eu estou pagando 'para frente'. Se você não é um newbee, por favor, desculpe o comprimento e verbosidade.

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \/; mv  \/\//' | bash

Onde:

ls -1 *_201[67][0-9]*

lista todos os arquivos correspondentes ao padrão, neste caso estou procurando por arquivos com a data no nome do arquivo no formato 'YYYYMMDD'

sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \/; mv  \/\//'
#        : | |    |     |                  | |       |                    |:                                 :
#        : |^2....^    ^3..................^^4.......^                    |:                                 :
#        :^1..............................................................^:                                 :
#        /................filename.................pattern................./...mkdir...and....mv...command.../

^ 1: primeiro grupo de captura - o nome do arquivo inteiro

^ 2: 2º grupo de captura - a primeira parte do padrão de nome de arquivo

^ 3: 3º grupo de captura - a segunda parte do nome do arquivo - aqui, a data como 'AAAAMMDD'

^ 4: quarto grupo de captura - parte do nome do arquivo opcional entre a data e a extensão, e a própria extensão

Sooooo .... se eu tiver um arquivo chamado

CallLog_555123412_20161231-214403.7z

... então

mkdir -p \/; mv  \/\/

na verdade significa

# make directory and sub-directory
mkdir -p CallLog_555123412/20161231
# move file from current directory to sub-sub-directory just created
mv CallLog_555123412_20161231-214403.7z CallLog_555123412/20161231/CallLog_555123412_20161231-214403.7z

Observe que a saída do comando sed é redirecionada para 'bash' para executá-lo. Para primeiro ver o arquivo proposto se mover sem realmente movê-los, primeiro remova o '| bash 'no final e tente assim:

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \/; mv  \/\//'

Isso não fará nenhuma alteração, mas você verá o comando que será executado SE você executá-lo com '| bash 'marcou no final.

Isso é útil porque você pode criar qualquer subdiretório que desejar em partes do nome do arquivo ou qualquer outra coisa adicionada ao texto 'replacement' no comando sed. Note que o sed exige muitos caracteres de escape.

colchetes Regex SED:

(...) exige escape para o agrupamento de captura - > \ (... \)

{m, n} exigem escape para quantificar o objeto anterior - > \ {m, n \}

/ requer escape na string de substituição - > \ /

[...] NÃO requer escape para classes de caracteres

\ 1 na string de substituição refere-se ao 1º grupo capturado, e assim por diante ...

AVISO DE SEGURANÇA: NUNCA TUBE NADA PARA 'bater', A MENOS QUE VOCÊ COMPREENDA INTEIRAMENTE O RESULTADO ...

Espero que ajude a eliminar alguns bloqueios:)

    
por 06.07.2017 / 17:02