Tengo un archivo temp
con algunos contenidos en minúsculas y mayúsculas.
Entrada
Contenido de mi temp
archivo:
hi Jigar GANDHI jiga
Quiero convertir todas las superiores a inferiores .
Comando
Intenté el siguiente comando:
sed -e "s/[A-Z]/[a-z]/g" temp
pero obtuve un resultado incorrecto.
Salida
Lo quiero como:
hi jigar gandhi jiga
Lo que debe estar en la parte sustituto del argumento para sed
?
Comentarios
- Ver también ¿Cómo convertir archivos txt UTF-8 a mayúsculas en bash?
Respuesta
Si su entrada solo contiene caracteres ASCII, puede usar tr
como:
o (menos fácil de recordar y escribir IMO; pero no limitado a letras latinas ASCII, aunque en algunas implementaciones incluyendo GNU tr
, todavía limitado a caracteres de un solo byte, por lo que en configuraciones regionales UTF-8, todavía limitado a letras ASCII):
tr "[:upper:]" "[:lower:]" < input
si tiene que usar sed
:
sed "s/.*/\L&/g" < input
(aquí asumiendo la implementación de GNU).
Con POSIX sed
, necesitaría especificar todas las transliteraciones y luego puede elegir cuál letras que desea convertir:
sed "y/AǼBCΓDEFGH.../aǽbcγdefgh.../" < input
Con awk
:
awk "{print tolower($0)}" < input
Comentarios
- Tenga en cuenta que
\L
es una extensión GNU. -
\L
funciona bien para mí hasta ahora. Ten en cuenta que estás tratando de hacer una extensión GNU - @JigarGandhi.
sed
es un comando de Unix. Los diferentes sistemas tienen diferentes variantes con diferente comportamiento y d funcionalidad. Afortunadamente, hoy en día, existe ‘ un estándar al que la mayoría se ajusta para que pueda contar con un conjunto mínimo de características comunes a todos.\L
no se encuentra entre ellos y fue introducido por GNUsed
(coincide con el mismo operador enex
/vi
) y generalmente no está disponible en otras implementaciones. - Tenga en cuenta que algunas
tr
implementaciones como GNUtr
don ‘ t funciona correctamente en configuraciones regionales de varios bytes (la mayoría de ellas lo son hoy en día, pruebeecho STÉPHANE | tr '[:upper:]' '[:lower:]'
por ejemplo). En los sistemas GNU, es posible que prefiera la variantesed
oawk
‘ stolower()
. - Ligera corrección:
sed 's/.*/\L&/g' < input
. La\1
referencia a la subcadena coincidente no ‘ funcionará a menos que especifiques la subcadena entre paréntesis como lo hace wurtle en la suya. Sin embargo, ‘ es un poco más limpio usar&
para representar la coincidencia completa, como se muestra
Respuesta
Usar vim, es muy simple:
$ vim filename gg0guGZZ
Abre el archivo, gg
va a la primera línea, 0
, primera columna. Con guG
, reduce las mayúsculas y minúsculas de todos los caracteres hasta el final del archivo. ZZ
guarda y sale.
Debe manejar casi cualquier cosa que le arroje; «Ignoraré los números, manejará los que no sean ASCII.
Si desea hacer lo contrario, convierta las letras minúsculas en mayúsculas, cambie el u
para un U
: gg0gUGZZ
y ya está.
Comentarios
- Lol » super simple »
- esto obviamente no ‘ t escala bien para muchos archivos
- @CoreyGoldberg
vim file1 file2 fileetc
y luego algo como:bufdo gg0guG:w<CR>
probablemente funciona para cualquier número de archivos. ¡Sin embargo, no lo he probado! - @TankorSmash que todavía no ‘ t escala a una gran cantidad de archivos
Responder
Me gusta dd
para esto, yo mismo.
<<\IN LC_ALL=C 2<>/dev/null \ dd conv=lcase hi Jigar GANDHI jiga IN
… obtiene …
hi jigar ghandi jiga
El LC_ALL=C
es para proteger los multibytes en la entrada, aunque no se convertirán las mayúsculas multibyte. Lo mismo es cierto para (GNU) tr
: ambas aplicaciones tienden a alterar las entradas en cualquier configuración regional que no sea C. iconv
se puede combinar con cualquiera para obtener una solución completa.
El 2>/dev/null
redirecciona descarta el informe de estado predeterminado de dd
«y su stderr. Sin él dd
seguiría la finalización de un trabajo como el anterior con información de impresión como cuántos bytes se procesaron, etc.
Comentarios
- Esta solución es mucho más rápida que
tr
cuando se manejan archivos grandes, ¡gracias!
Respuesta
También puede utilizar Perl 5:
perl -pe "$_=lc" temp
La opción -p
indica perl para ejecutar la expresión especificada una vez para cada línea de entrada, imprimiendo el resultado, es decir, el valor final de $_
. -e
indica que el El programa será el siguiente argumento, a diferencia de un archivo que contenga el script. lc
convierte a minúsculas. Sin un argumento, funcionará en $_
. Y $_=
lo guarda de nuevo para que se imprima.
Una variación de eso sería
perl -ne "print lc" temp
Usando -n
es como -p
excepto que $_
no se imprimirá al final. Entonces, en lugar de guardar en esa variable, incluyo una declaración de impresión explícita.
Un beneficio de Perl en contraste con sed es que no necesita ninguna extensión GNU. Hay proyectos que tienen que ser compatibles con entornos que no son GNU pero que también tienen una dependencia de Perl. En comparación con tr
, es posible que Perl lc
se pueda hacer más fácilmente compatible con la configuración regional. Consulte la página de manual perllocale
para obtener más detalles.
Respuesta
Necesita capturar el patrón coincidente y luego úselo en el reemplazo con un modificador:
sed "s/\([A-Z]\)/\L\1/g" temp
El \(...\)
«captura» el adjuntando texto coincidente, la primera captura va a \1
, la siguiente a \2
, etc. La numeración es de acuerdo con los corchetes de apertura en caso de capturas anidadas.
El \L
convierte el patrón capturado a minúsculas, también hay \U
para mayúsculas .
Comentarios
- no es necesario que haga esto; todo el patrón siempre se captura en
&
- Cierto, pero entonces habría perdido la oportunidad de explicar la captura de coincidencias 🙂
Respuesta
Además de la respuesta de MvG, también puede usar Perl 6:
perl6 -pe .=lc temp
Aquí $ _ está implícito, y no necesita las comillas simples para protegerlo de la expansión del shell ($ _ es un parámetro especial de Bash; ver: https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html )