Agregar extensión de archivo a archivos con bash

94

¿Cuál es la buena manera de agregar la extensión de archivo ".jpg" a archivos sin extensión con bash?

Adrian
fuente
3
mv "${file}" "${file}.jpg"?
onteria_
2
en su opinión, ¿qué es un "archivo sin extensión"? ¿Es un archivo sin un punto en el nombre?
Glenn Jackman

Respuestas:

118
for f in *.jpg; do mv "$f" "${f%.jpg}"; done
for f in *; do mv "$f" "$f.jpg"; done
Seth Robertson
fuente
8
el segundo es perfecto para renombrar archivos sin extensión. ¡Gracias!
anon58192932
2
segundo añade una extensión en todos los archivos, no sólo los sin extensión
Jeff
5
al igual que una nota "${f%.jpg}"es la manipulación de cadenas de shell bash. `$ {string% substring}` Elimina la coincidencia más corta de $ substring de la parte posterior de $ string.
Jichao
Advertencia: si tiene una carpeta con extensiones mixtas, sepa que lo anterior se suma .jpgincluso a los archivos normales.
sachinruk
61

Puede usar el cambio de nombre:

rename 's/(.*)/$1.jpg/' *
Kim Stebel
fuente
3
¿Qué versión de cambio de nombre estás usando? El mío tiene diferentes argumentos:rename from to file...
B Johnson
1
El cambio de nombre se incluye con perl, que es la versión 5.10.1.
Kim Stebel
3
Esto funciona muy bien con el cambio de nombre incluido en Ubuntu (y supongo que todas las distribuciones basadas en Debian), mucho menos detallado que la respuesta de jm666.
Roger Heathcote
28

Otra forma, sin bucles

find . -type f -not -name "*.*" -print0 |\
xargs -0 file |\
grep  'JPEG image data' |\
sed 's/:.*//' |\
xargs -I % echo mv % %.jpg

Descompostura:

  • encontrar todos los archivos sin extensión
  • comprobar el tipo de archivo
  • filtrar solo archivos JPG
  • eliminar información de tipo de archivo
  • xargs ejecuta el "mv" para cada archivo

el comando anterior es para ejecución en seco , después debe eliminar el "eco" antes de mv

EDITAR Algunas personas sugieren que aquí se necesita "Ajustar los argumentos de la ruta entre comillas; evita la división de argumentos en las rutas con espacios" .

Por lo general, esta recomendación es cierta, en este caso no lo es. Porque, aquí %se reemplaza no por la expansión del shell sino por el xargsinterno (directamente), por lo %que se sustituirá correctamente incluso con espacios en los nombres de archivo.

Demostración simple:

$ mkdir xargstest
$ cd xargstest

# create two files with spaces in names
$ touch 'a b' 'c d'

$ find . -type f -print
./c d
./a b
# notice, here are spaces in the above paths

#the actual xargs mv WITHOUT quotes
$ find . -type f -print | xargs -I % mv % %.ext

$ find . -type f -print
./a b.ext
./c d.ext
# the result is correct even in case with spaces in the filenames...
jm666
fuente
Puede poner esto en un bucle y estos xargs son superfluos. Me gusta más la respuesta de Ryan en esta situación.
Lucius
1
@Lucius - por cierto, la pregunta quiere archivos "sin extensión" - así que Ryan debería encontrar solo esos ...
jm666
@ jm666 ¡oye! ¿Cómo modifico su fragmento de código para cambiar el nombre de todos los archivos sin extensión en una carpeta a sus respectivas extensiones? (Estoy detectando extensiones correctas por el comando file -b $ filename.)
Soumyajit
24

Simple, vaya al directorio donde están sus archivos y:

for f in *;do mv $f $f.jpg;done
bharat
fuente
Por alguna razón, esto funciona para mí, pero la solución de Seth con comillas no. (OSX Mountain Lion bash)
delrocco
4
Sería mejor si se usara for f in *;do mv "$f" "$f".jpg;donepara admitir espacios en nombres de archivos.
Hritik
Gracias por esta solución elegante y simple: he encontrado esta respuesta varias veces, pero parece que no puedo memorizarla. #dejavu
Tim Andersen
15

funcionamiento en seco:

 rename -n s/$/.jpg/ *

cambio de nombre real:

 rename s/$/.jpg/ *
Alexey
fuente
6
find . | while read FILE; do if [ $(file --mime-type -b "$FILE") == "image/jpeg" ]; then mv "$FILE" "$FILE".jpg; fi; done;
Ryan Li
fuente
1

En mi caso, no conocía el tipo de archivo, así que utilicé el comando mv con la ayuda del comando de archivo para examinar y posiblemente encontrar el tipo de archivo. Es posible que esta solución no sea perfecta para todos los archivos, ya que es posible que el comando de archivo no reconozca el tipo de archivo, pero funcionó muy bien para mí.

for f in *; do ext=$(file $f | awk '{print $2;}'); mv -n "$f" "$f.$ext"; done

El uso de awk es quitar la segunda palabra de la cadena devuelta del archivo de comando que es en realidad la extensión.

Paolo
fuente
maneja jpg y png automáticamente. lo usé y funciona - ¡muchas gracias! Solo que ahora las extensiones son CAPS. aunque pequeño problema :)
krivar
0
rename --dry-run * -a ".jpg" # test  
* -a ".jpg" # rename
Roman Rhrn Nesterov
fuente
--dry-runy -ano están disponibles en mi versión de rename. Si esto es específico de alguna arquitectura, debe especificarse.
Fernando César
0

Puede usar mover varios archivos . Soy un mantenedor de este proyecto. La sintaxis es simple.

mmf files*

Abrirá su $ EDITOR con todos los nombres de archivos, o vim por defecto y puede simplemente resaltar el final de todos los nombres de archivos usando Ctrl + v + G en vim, guardar el archivo, salir y eso, todos sus archivos serán renombrados

Almas Abdrazak
fuente
-2

Ryan Li

La sintaxis correcta para agregar una extensión de archivo a varios archivos dentro de un directorio que no tiene una extensión de archivo es

find . | while read FILE; do if [[ -n `file --mime-type "$FILE" | grep 'message/rfc822'` ]]; then  mv "$FILE" "$FILE".eml; fi; done;
Dillon Beresford
fuente