Anexar texto aos nomes de arquivos que não contêm um ponto

9

Dados os seguintes arquivos:

english_api
english_overview
style.css

Eu quero obter:

english_api.html
english_overview.html
style.css

Em outras palavras, como acrescentar um texto a todos os arquivos que não contêm um ponto ( .) em um diretório usando o terminal.

Obviamente, existem muitos arquivos nessa pasta; Eu acabei de escrever 3 como um exemplo.

Se eu fosse, digamos, substitua .csspor .htmlnessa pasta, eu usaria:

rename .css .html *.css

Mas não consigo realmente pensar em uma maneira de combinar arquivos que não contêm algo. Também como acrescentar (vs substituir) usando o renamecomando?

Bor691
fonte

Respostas:

13

Tente este findcomando,

find . -type f ! -name "*.*" -exec mv {} {}.html \;

Ele renomeia os arquivos que não contêm pontos em seus nomes de arquivos presentes no diretório atual para este filename.htmlformato ( adicionados .htmlno final ).

. -> Representa o diretório atual

-type f -> Para fazer esta operação apenas em arquivos.

! -name "*.*" -> imprime o nome dos arquivos que não têm pontos no nome.

-exec mv {} {}.html -> findexecute esta operação de mudança (ou) renomear nos nomes de arquivos extraídos.

\; -> Representa o fim do findcomando.

Avinash Raj
fonte
6

No bash, você pode usar globs de shell estendidos, por exemplo

for file in path/to/files/!(*.*); do echo mv "$file" "$file.html"; done

(remova echoquando confirmar que está correspondendo ao padrão correto). Se o globbing estendido ainda não estiver ativado, você poderá ativá-lo shopt -s extglob.

Outra opção é usar a renamefunção baseada em perl com um regex que exclui literal.

rename -nv 's/^[^.]+$/$&.html/' path/to/files/*

(remova a nopção depois de confirmar que está correspondendo ao padrão correto).

chave de aço
fonte
for file in path/to/files/!(*.*); do echo mv "$file" "$file.html"; doneO comando renomeia os diretórios também.
Avinash Raj
2

O meu preferido em casos como este é mmv. Não é instalado por padrão no Ubuntu, mas você pode instalar usando o sudo apt-get install mmvcomando

No seu caso, você precisa usá-lo duas vezes:

  1. Renomeie todos os arquivos do diretório atual adicionando .htmlno final de cada nome de arquivo:

    mmv -v '*' '#1.html'
    
  2. Renomeie novamente (voltar) todos os arquivos que tinham anteriormente em seus nomes um ou mais .(pontos):

    mmv -v '*.*.html' '#1.#2'
    

Ou, em uma linha:

mmv -v '*' '#1.html' && mmv -v '*.*.html' '#1.#2'

-vopção não é obrigatória. Eu o uso apenas para uma saída detalhada, porque sem ele mmvexecuta ações silenciosamente.

Veja man mmvpara mais informações.

Radu Rădeanu
fonte
1

Com o comando Perl rename ( prename), você pode adicionar uma condição de que o nome do arquivo deve conter um ponto. Se o snippet Perl não alterar o nome de um arquivo, ele permanecerá intocado. Aqui estão algumas maneiras de escrever isso:

prename '/\./ or s/$/.html/' *
prename 's/$/.html/ unless /\./' *
prename '$_ .= ".html" unless /\./' *
prename '$_ = "$_.html" unless /\./' *
prename 'if (!/\./) {$_ = "$_.html"}' *
Gilles 'SO- parar de ser mau'
fonte
-2

As respostas são perfeitas, eu também lhe dou outro comando que faz este trabalho:

ls -1 | grep -v "\." | awk '{print "mv "$0" "$0".html"}' | sh

Alguma explicação:

ls - list directory contents

 -1     list one file per line

grep prints the matching lines.

-v, --invert-match
              Invert the sense of matching, to select non-matching lines.  (-v
              is specified by POSIX.)

Awk is mostly used for pattern scanning and processing. It searches one or more files to see if they contain lines that matches with the specified patterns and then perform associated actions.

NOTA :

Eu tento o seu cenário e o comando faz o trabalho.

nux
fonte
6
Isso falha nos nomes de arquivos que contêm qualquer tipo de espaço em branco (espaços, guias, novas linhas etc.). Como regra geral, você nunca deve analisarls .
terdon
Isso é terdon certo agradecer pelo seu comentário, mas como posso resolver isso no mesmo comando
nux
3
Você não pode realmente. Não há quase nenhuma maneira segura de analisar. Se você realmente deseja fazer isso usando awke sh, tente algo como printf "'%s'\n" -- !(*.*) | awk '{print "mv -- "$0" "$0".html"}' | sh. Isso ainda será interrompido nos nomes de arquivos com novas linhas, mas pelo menos poderá lidar com espaços. O --é necessário para casos onde você tem os nomes de arquivos que começam com -.
terdon