2012-09-17 20 views
5

Me gustaría cambiar los nombres de archivo en minúsculas a mayúsculas con awk/sed/bashcambiar los nombres de archivo en minúsculas a mayúsculas con awk, sed o fiesta

su ayuda se agradece

aaaa.txt 
vvjv.txt 
acfg.txt 

salida deseada

AAAA.txt 
VVJV.txt 
ACFG.txt 
+0

1.He utilizado estos consejos para cambiar mis nombres de archivo divertidos con un bash one-liner: para mí en ./*.*; hacer mv "$ i" "$ (echo" $ i "| tr '[:? = &]' '[_]')"; hecho ; 2. Cruce la referencia de fyi para tratar incluso los caracteres unicode más extraños: http://stackoverflow.com/questions/3011569/how-do-i-convert-filenames-from-unicode-to-ascii – AnneTheAgile

Respuesta

15

Prefacio:

Si no se preocupan por el caso de las extensiones, basta con utilizar la utilidad 'tr' en un bucle shell:

for i in *.txt; do mv "$i" "$(echo "$i" | tr '[a-z]' '[A-Z]')"; done 

Si no se preocupan por el caso de las extensiones, entonces usted debe ser consciente de que hay más de una forma de hacerlo (TIMTOWTDI). Personalmente, creo que la solución Perl, enumerada aquí, es probablemente la solución más simple y flexible en Linux. Si tiene varias extensiones de archivo, simplemente especifique el número que desea mantener sin cambios. La solución BASH4 también es muy buena, pero debe estar dispuesto a escribir la extensión varias veces o, alternativamente, usar otra variable para almacenarla. Pero si necesita una portabilidad seria, le recomiendo la última solución en esta respuesta que usa octals. Algunos de los sabores de Linux también incluyen una herramienta llamada , cambie el nombre que también puede valer la pena visitar. Su uso variará de la distribución a la distribución, así que escriba man rename para obtener más información.

SOLUCIONES:

Usando Perl:

# single extension 
perl -e 's/\.[^\.]*$/rename $_, uc($`) . $&/e for @ARGV' *.txt 

# multiple extensions 
perl -e 's/(?:\.[^\.]*){2}$/rename $_, uc($`) . $&/e for @ARGV' *.tar.gz 

Usando BASH4:

# single extension 
for i in *.txt; do j="${i%.txt}"; mv "$i" "${j^^}.txt"; done 

# multiple extensions 
for i in *.tar.gz; do j="${i%.tar.gz}"; mv "$i" "${j^^}.tar.gz"; done 

# using a var to store the extension: 
e='.tar.gz'; for i in *${e}; do j="${i%${e}}"; mv "$i" "${j^^}${e}"; done 

Usando GNU awk:

for i in *.txt; do 

    mv "$i" $(echo "$i" | awk '{ sub(/.txt$/,""); print toupper($0) ".txt" }'); 
done 

Usando GNU sed:

for i in *.txt; do 

    mv "$i" $(echo "$i" | sed -r -e 's/.*/\U&/' -e 's/\.TXT$/\u.txt/'); 
done 

Usando BASH3.2:

for i in *.txt; do 

    stem="${i%.txt}"; 

    for ((j=0; j<"${#stem}"; j++)); do 

     chr="${stem:$j:1}" 

     if [[ "$chr" == [a-z] ]]; then 

      chr=$(printf "%o" "'$chr") 

      chr=$((chr - 40)) 

      chr=$(printf '\'"$chr") 
     fi 

     out+="$chr" 
    done 

    mv "$i" "$out.txt" 

    out= 
done 
+0

n.b. sed solution no es compatible con Mac/Darwin/BSD (¿no es Linux?) * sed * – Orwellophile

+0

@Orwellophile: GNU sed no está BSD sed. BSD es Linux, como GNU es Linux. – Steve

+0

Tampoco funciona con Solaris. (Eso es SYSV). Pero su corrección es notada. No funciona con versiones no GNU de ** sed ** – Orwellophile

9

En general, para las modificaciones en minúsculas/mayúsculas se usa a menudo la utilidad "tr" (traducir caracteres), es del conjunto de utilidades de línea de comandos utilizadas para la sustitución de caracteres.

dtpwmbp:~ pwadas$ echo "xxx" | tr '[a-z]' '[A-Z]' 
XXX 
dtpwmbp:~ pwadas$ 

Además, para cambiar el nombre de los archivos que hay "cambiar el nombre de" utilidad, entregado con el Perl (renombrar hombre).

SYNOPSIS 
     rename [ -v ] [ -n ] [ -f ] perlexpr [ files ] 

DESCRIPTION 
     "rename" renames the filenames supplied according to the rule specified as the first argument. The perlexpr argument is a Perl expression which is expected to modify the $_ string in 
    Perl for at least some of the filenames specified. If a given filename is not modified by the expression, it will not be renamed. If no filenames are given on the command line, 
    filenames will be read via standard input. 

    For example, to rename all files matching "*.bak" to strip the extension, you might say 

      rename 's/\.bak$//' *.bak 

    To translate uppercase names to lower, you'd use 

      rename 'y/A-Z/a-z/' * 
1
for f in *.txt; do 
    mv "$f" "`tr [:lower:] [:upper:] <<< "${f%.*}"`.txt" 
done 
+0

Eso capitalizará la extensión "txt". Además, con bash, use una cadena aquí: 'tr [: upper] [: lower:] <<<" $ f "' –

+0

@glennjackman Buen punto. '$ {f%. *}' debería encargarse de eso. Fijo. –

1

Bash expansión de 4 parámetros puede realizar caso cambia:

for i in *.txt; do 
    i="${i%.txt}" 
    mv "$i.txt" "${i^^?}.txt" 
done 
1

bash:

for f in *.txt; do 
    no_ext=${f%.txt} 
    mv "$f" "${no_ext^^}.txt" 
done 
0

Esto podría funcionar para usted (GNU SED):

printf "%s\n" *.txt | sed 'h;s/[^.]*/\U&/;H;g;s/\(.*\)\n/mv -v \1 /' | sh 

o más simplemente:

printf "%s\n" *.txt | sed 'h;s/[^.]*/\U&/;H;g;s/\(.*\)\n/mv -v \1 /e' 
4

se recomienda usar rename, si sólo quiere a mayúsculas el nombre de archivo y no la extensión, usar algo como esto:

rename -n 's/^([^.]*)\.(.*)$/\U$1\E.$2/' * 

\U las mayúsculas todo hasta \E, ver perlreref(1). Retire el -n cuando esté satisfecho con la salida.

+0

Puede agregar^y $ anchors, y explícitamente requiere el '.', Por lo que la coincidencia no depende de que la sección de expresiones regulares sea codiciosa o floja; simplemente lo hace más legible en mi humilde opinión. –

+0

Eso se ajusta mejor a lo que quiere el OP. He agregado tus sugerencias – Thor

1

Un enfoque más sencillo, ligero y portátil sería:

for i in *.txt 
do 
    fname=$(echo $i | cut -d"." -f1 | tr [a-z] [A-Z]) 
    ext=$(echo $i | cut -d"." -f2) 
    mv $i $fname.$ext 
done 

Esto funcionaría en casi todas las versiones de BASH ya que estamos utilizando utilidades externas más comunes (corte, tr) que se encuentra en todos los sabores de Unix.

1

Basta con utilizar (en el terminal):

for i in *.txt; do mv $i `echo ${i%.*} | tr [:lower:] [:upper:]`.txt; done; 
0
for i in *.jar; do mv $i `echo ${i%} | tr [:upper:] [:lower:]`; done; 

esto funciona para mí.

Cuestiones relacionadas