Agregar texto a los nombres de archivo que no contienen un punto

9

Dados los siguientes archivos:

english_api
english_overview
style.css

Quiero tener:

english_api.html
english_overview.html
style.css

En otras palabras, cómo agregar un texto a todos los archivos que no contienen un punto ( .) dentro de un directorio usando terminal.

Obviamente hay muchos archivos en esa carpeta; Acabo de escribir 3 como ejemplo.

Si tuviera que, digamos, reemplace .csscon .htmlen esa carpeta, yo utilizo:

rename .css .html *.css

Pero realmente no puedo pensar en una forma de hacer coincidir los archivos que no contienen algo. ¿También cómo agregar (vs reemplazar) usando el renamecomando?

Bor691
fuente

Respuestas:

13

Prueba este findcomando,

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

Cambia el nombre de los archivos que no contienen puntos en sus nombres de archivo presentes en el directorio actual a este filename.htmlformato ( agregado .htmlal final ).

. -> Representa el directorio actual

-type f -> Para hacer esta operación solo en archivos.

! -name "*.*" -> imprime el nombre de los archivos que no tienen puntos en su nombre.

-exec mv {} {}.html -> el findcomando realiza esta operación de cambio de nombre (o) en los nombres de archivo extraídos.

\; -> Representa el final del findcomando.

Avinash Raj
fuente
6

En bash, puedes usar globos de concha extendidos, por ejemplo

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

(elimine el echoque haya confirmado que coincide con el patrón correcto). Si el globbing extendido aún no está habilitado, puede habilitarlo con shopt -s extglob.

Otra opción es usar la renamefunción basada en perl con una expresión regular que excluye literal.

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

(elimine la nopción una vez que haya confirmado que coincide con el patrón correcto).

conductor de acero
fuente
for file in path/to/files/!(*.*); do echo mv "$file" "$file.html"; donecomando cambia el nombre de los directorios también.
Avinash Raj
2

Mi preferido en casos como este es mmv. No está instalado por defecto en Ubuntu, pero puede instalarlo usando el sudo apt-get install mmvcomando.

En su caso, debe usarlo dos veces:

  1. Cambie el nombre de todos los archivos del directorio actual agregando .htmlal final de cada nombre de archivo:

    mmv -v '*' '#1.html'
    
  2. Cambie el nombre nuevamente (atrás) de todos los archivos que previamente tenían en sus nombres uno o más .(puntos):

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

O, en una línea:

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

-vLa opción no es obligatoria. Lo uso solo para una salida detallada porque sin él mmvrealiza acciones en silencio.

Ver man mmvpara más información.

Radu Rădeanu
fuente
1

Con el comando Perl rename ( prename), puede agregar una condición de que el nombre del archivo debe contener un punto. Si el fragmento de Perl no cambia el nombre de un archivo, ese archivo no se modifica. Aquí hay algunas maneras de escribir esto:

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

Las respuestas son perfectas, también te doy otro comando que hace este trabajo:

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

Alguna explicación:

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 :

Intento su escenario y el comando hace el trabajo.

nux
fuente
66
Esto falla en los nombres de archivo que contienen cualquier tipo de espacio en blanco (espacios, pestañas, líneas nuevas, etc.). Como regla general, nunca debe analizarls .
terdon
Eso es correcto, gracias por tu comentario, pero ¿cómo puedo resolver esto con el mismo comando
Nux
3
No puedes realmente. Hay casi no hay manera segura de analizar ls. Si realmente quieres hacerlo usando awky sh, prueba algo como printf "'%s'\n" -- !(*.*) | awk '{print "mv -- "$0" "$0".html"}' | sh. Eso todavía se romperá en los nombres de archivo con nuevas líneas, pero al menos puede tratar con espacios. El --es necesaria para los casos en los que tienen nombres de archivo que comienzan con -.
terdon