Como alterar a extensão de todos os arquivos em um diretório? [duplicado]

4

Existem alguns arquivos sem extensão no diretório atual (não há pontos em seus nomes).

Eu quero renomear assim:

filename -> filename.md

Eu tentei fazer mv * *.md , mas isso não ajudou.

Estou interessado em uma função que leva um argumento para a extensão e renomeia de acordo, e a outra para que os arquivos executem a operação.

    
por Santosh Kumar 23.03.2013 / 18:04

4 respostas

10

Os padrões são correspondidos pelo shell, não pelo comando, então o que você tentou não teve chance de funcionar: primeiro o shell expande * para todos os arquivos (não apenas os sem extensão: você nunca disse nada sobre os arquivos não terem um . em seu nome) e *.md para todos os arquivos cujo nome em .md ; então o shell passa a concatenação das duas listas para o comando mv .

Em zsh

Em zsh, execute o seguinte comando uma vez (coloque-os em ~/.zshrc para o futuro):

autoload -U zmv
# you don't need the following two now, but put them also in your .zshrc
alias zcp='zmv -C'
alias zln='zmv -L'

Você pode então executar zmv para renomear arquivos de acordo com um padronizar. Tanto o padrão e o texto de substituição precisam ser citados para que sejam transmitidos como é para a função zmv que irá expandi-los no devido tempo.

zmv '^*.*' '$f.md'

Observe as aspas simples ao redor dos dois argumentos: o padrão e a expressão de substituição devem ser passados literalmente para a função zmv .

^*.* significa todos os arquivos, exceto os que correspondem a *.* , é um atalho para *~*.* (ambos são extensões zsh para a sintaxe de padrão tradicional). Se você quiser usar esse padrão fora de zmv , será necessário executar setopt extended_glob primeiro (coloque isso em .zshrc também).

No bash

O Bash não possui essa ferramenta conveniente, então você precisa recorrer a um loop. Primeiro, ative extensões de globulação ksh; isso é algo que você deve colocar em yout ~/.bashrc .

shopt -s extglob

Agora você pode usar o operador !(PATTERN) para corresponder aos arquivos sem extensão.

for x in !(*.*); do
  mv -- "$x" "$x.md"
done

As aspas duplas em $x são necessárias no caso de os nomes dos arquivos conterem espaços em branco ou caracteres globbing. O -- após o nome do comando é necessário no caso de um nome de arquivo começar com - .

Em qualquer casca

Se você não tiver o operador !(…) , poderá fazer um loop em todos os arquivos e testar cada nome de arquivo dentro do loop.

for x in *; do
  case "$x" in
    *.*) ;;         # skip this file
    *) mv -- "$x" "$x.md";;
  esac
done
    
por 23.03.2013 / 22:32
3

Você pode fazer isso com rename (aquele que vem com perl às vezes renomeado prename ). Se houver outros arquivos no diretório, você precisará excluí-los da seguinte maneira com um extglob:

shopt -s extglob
rename s/$/.md/ -- !(*.*)
    
por 23.03.2013 / 18:09
2

Pode haver uma maneira mais simples, mas esta é bastante simples e a forma geral é adaptável a todos os tipos de propósitos:

for name in *; do 
    if [ -f "$name" ]; then 
        mv -- "$name" "$name.md"
    fi
done

Também pode ser transformado em uma função.

    
por 23.03.2013 / 18:23
2

Encontrou uma resposta curta aqui (que também suporta renomeação, que é o que Eu estava procurando quando encontrei esta página):

for f in *.OLDNAME; do mv $f 'basename $f .OLDNAME'.NEWNAME; done;

Isso também funciona para adicionar ou remover extensões, é claro:

# Adding extension
for f in *; do mv $f ${f}.NEWNAME; done; # No need to use basename here -- just adding a new extension

# Removing extension
for f in *.OLDNAME; do mv $f 'basename $f .OLDNAME'; done;
    
por 11.09.2014 / 02:59

Tags