2010-12-11 12 views
6

Ejecuto un script que genera aproximadamente 10k archivos en un directorio. Acabo de descubrir que hay un error en el script que hace que algunos nombres de archivo tengan un retorno de carro (presumiblemente un carácter '\ n').comando sed para arreglar nombres de archivos en un directorio

Quiero ejecutar un comando sed para eliminar el retorno de carro de los nombres de archivo.

¿Alguien sabe qué params pasar a sed para limpiar los nombres de los archivos de la manera descrita?

estoy corriendo Linux (Ubuntu)

Respuesta

7

No sé cómo sed haría esto, pero esta secuencia de comandos python debería hacer el truco :.

Esto no es sed, pero me parece python mucho más fácil de usar al hacer cosas como éstas:

#!/usr/bin/env python 

import os 

files = os.listdir('.') 

for file in files: 
    os.rename(file, file.replace('\r', '').replace('\n', '')) 
    print 'Processed ' + file.replace('\r', '').replace('\n', '') 

Se despoja de cualquier ocurrencia tanto \r y \n de todos los nombres de archivo en un directorio dado .

Para ejecutarlo, guárdelo en algún lugar, cd en su directorio de destino (con los archivos que se procesarán), y ejecute python /path/to/the/file.py.

Además, si planea hacer más renombrado de lotes, considere Métamorphose. Es una GUI realmente agradable y poderosa para esto. Y, es gratis!

¡Buena suerte!


En realidad, intente esto: cd en el directorio, el tipo de python, y luego simplemente pegar esto en:

exec("import os\nfor file in os.listdir('.'):\n os.rename(file, file.replace('\\r', '').replace('\\n', ''))\n print 'Processed ' + file.replace('\\r', '').replace('\\n', '')") 

Es una versión de una sola línea del script anterior, y usted don' tengo que guardarlo


Versión 2, con facultad de sustitución espacio:

#!/usr/bin/env python 

import os 

for file in os.listdir('.'): 
    os.rename(file, file.replace('\r', '').replace('\n', '').replace(' ', '_') 
    print 'Processed ' + file.replace('\r', '').replace('\n', '') 

Y aquí está la de una sola línea:

exec("import os\nfor file in os.listdir('.'):\n os.rename(file, file.replace('\\r', '').replace('\\n', '')replace(' ', '_'))\n print 'Processed ' + file.replace('\\r', '').replace('\\n', '');") 
+0

@blender: gracias por el guión. Lo ejecuto bien, pero los nombres de los archivos todavía están 'divididos' en múltiples líneas. ¿Qué otro personaje podría estar causando esto? Obviamente, \\ r y \\ n no son los culpables aquí :( – skyeagle

+0

¿Estás seguro de que no se trata de envoltorios y espacios? Para mí, los nombres de archivos largos se dividen a lo largo de los espacios. Si quieres, podría modificarlo para reemplazar los espacios. con guiones bajos.Tal vez eso ayudaría? – Blender

+0

También he publicado un script de reemplazo de espacio. Pruébalo, quizás eso funcione? Ningún otro caracter además de '\ n' y' \ r' causa saltos de línea. Podría ser solo su administrador de archivos ... – Blender

1

EDIT: Si realmente quieres con sed, echar un vistazo a esto:

algo en este sentido debería funcionar similar al perl a continuación:

for i in *; do echo mv "$i" `echo "$i"|sed ':a;N;s/\n//;ta'`; done 

con Perl, probar algo a lo largo de estas líneas:

for i in *; do mv "$i" `echo "$i"|perl -pe 's/\n//g'`; done 

Esto cambiará el nombre de todos los archivos en la carpeta actual mediante la eliminación de todos los caracteres de nueva línea de ellos. Si necesita ir recursivo, puede usar find en su lugar; sin embargo, tenga en cuenta el escape en ese caso.

+0

Nadie puede averiguar cómo hacerlo con 'sed';) – Blender

+0

He editado para agregar la solución' sed' - cuando respondí por primera vez utilicé 'perl' ya que' sed' no es una herramienta adecuada para líneas múltiples edición (como se puede ver en la línea, Perl One es mucho más simple de seguir). –

+0

Meh, todavía prefiero Python sobre 'sed' cualquier día. Es mucho más fácil trabajar con él. – Blender

4

Si no hay espacios en los nombres de archivo, que puede hacer:

for f in *$'\n'; do mv "$f" $f; done 

No funcionará si th Las líneas nuevas están incorporadas, pero funcionarán para las nuevas líneas finales.

Si tiene que usar sed:

for f in *$'\n'; do mv "$f" "$(echo "$f" | sed '/^$/d')"; done 

Usando el guión rename Perl:

rename 's/\n//g' *$'\n' 

o la utilidad util-linux-ng:

rename $'\n' '' *$'\n' 

Si el carácter es un retorno en lugar de una nueva línea, cambie \n o ^$ a \r en cualquier lugar que aparezcan arriba.

+0

¿Por qué el voto a favor? –

+0

De vuelta en cero;) No estoy seguro de por qué las personas simplemente votan negativamente al azar. Probablemente los novatos que obtuvieron el privilegio querían obtener esa nueva insignia ... – Blender

+0

@Blender: Gracias. Una para ti está en camino. –

2

La razón por la que no obtiene ninguna respuesta pura sed es que fundamentalmente sed edita el contenido del archivo, no los nombres de los archivos; por lo tanto, las respuestas que usan sed hacen algo así como hacer eco del nombre del archivo en una tubería (pseudo archivo), editarlo con sed, luego usar mv para convertirlo nuevamente en un nombre de archivo.

Desde sed está fuera, aquí es una versión pura-fiesta para añadir a la Perl, Python, etc guiones que tiene hasta ahora:

killpattern=$'[\r\n]' # remove both carriage returns and linefeeds 
for f in *; do 
    if [[ "$f" == *$killpattern* ]]; then 
     mv "$f" "${f//$killpattern/}" 
    fi 
done 

... pero desde ${var//pattern/replacement} no está disponible en la llanura sh (junto con [[...]]), aquí está utilizando una versión sh sintaxis -sólo y tr para hacer la sustitución de caracteres:

for f in *; do 
    new="$(printf %s "$f" | tr -d "\r\n")" 
    if [ "$f" != "$new" ]; then 
     mv "$f" "$new" 
    fi 
done 
0

de hecho, hay una manera de usar sed:

carr='\n'          # specify carriage return 
files=($(ls -f))        # array of files in current dir 
for i in ${files[@]} 
do 
    if [[ -n $(echo "$i" | grep $carr) ]]  # filenames with carriage return 
    then 
     mv "$i" "$(echo "$i" | sed 's/\\n//g')" # move! 
    fi 
done 

Esto realmente funciona.

Cuestiones relacionadas