Estoy tratando de usar SED para extraer texto de un archivo de registro. Puedo buscar y reemplazar sin demasiados problemas:
sed 's/foo/bar/' mylog.txt
Sin embargo, quiero que la búsqueda no distinga entre mayúsculas y minúsculas. Por lo que busqué en Google, parece que agregar ial final del comando debería funcionar:
sed 's/foo/bar/i' mylog.txt
Sin embargo, esto me da un mensaje de error:
sed: 1: "s/foo/bar/i": bad flag in substitute command: 'i'
¿Qué va mal aquí y cómo lo soluciono?
macos
replace
sed
case-insensitive
Craig Walker
fuente
fuente

Ies una extensión GNU que puede no estar disponible con su copia de sed.man sedES coherente con la implementación: no se menciona (y no se admite en la práctica) la coincidencia que no distingue entre mayúsculas y minúsculas; Si encuentra algún documento que indique lo contrario, háganoslo saber.gprefijo, por lo que puedo usargsedogdatecuando necesito una función que no se encuentra en la versión estándar.Respuestas:
Para ser claros: en macOS , a partir de Mojave (10.14),
sedque es la implementación de BSD , NO admite la coincidencia que no distingue entre mayúsculas y minúsculas , es difícil de creer, pero es cierto. La respuesta aceptada anteriormente , que en sí misma muestra un comando GNUsed, ganó ese estado debido a laperlsolución basada en la mencionada en los comentarios.Para que la solución Perl también funcione con caracteres extranjeros , a través de UTF-8, use algo como:
-Cactiva la compatibilidad con UTF-8 para transmisiones y archivos, asumiendo que la configuración regional actual está basada en UTF-8.-Mutf8le dice a Perl que interprete el código fuente como UTF-8 (en este caso, la cadena pasada a-pe) - este es el equivalente más corto del más detallado-e 'use utf8;'.Gracias, Mark Reed(Tenga en cuenta que el uso
awktampoco es una opción , ya queawken macOS (es decir, BWK awk , también conocido como BSD awk ) parece desconocer por completo las configuraciones regionales: sus funcionestolower()ytoupper()ignoran los caracteres extranjeros (ysub()/gsub()no tienen indicadores que no distingan entre mayúsculas y minúsculas para empezar con).)fuente
Nota del editor : esta solución no funciona en macOS (lista para usar), porque solo se aplica a GNU
sed, mientras que macOS viene con BSDsed.Escriba con mayúscula la "I".
fuente
Isufijo no es un uso portátil desed. POSIXsedusa solo Expresiones regulares básicas (BRE), que son sorprendentemente limitadas. Ni siquiera admiten+(tienes que usar\{1,\}en su lugar), y mucho menos la coincidencia que no distingue entre mayúsculas y minúsculas. La única forma portátil de hacerlo con sed es buscar algo como/[hH][eE][lL][lL][oO]/, que a menudo no será práctico./gIcontrario, solo funcionará en el primer partido.Otra solución alternativa para
sedMac OS X es instalargseddesde MacPorts o HomeBrew y luego crear el aliassed='gsed'.fuente
brew install gnu-sedluego fue a mi ~ / .bash_profile y agregué el alias. Gracias @davmatbrew install gnu-sed --with-default-names: esto anulará el valor predeterminadosed.Las preguntas frecuentes de sed abordan la búsqueda que no distingue entre mayúsculas y minúsculas . Señala que a) muchas versiones de sed admiten una bandera para él yb) es incómodo hacerlo en sed, debería usar awk o Perl.
Pero para hacerlo en POSIX sed, sugieren tres opciones (adaptadas para sustitución aquí):
Convierta a mayúsculas y almacene la línea original en el espacio de espera; Sin embargo, esto no funcionará para sustituciones, ya que el contenido original se restaurará antes de imprimir, por lo que solo es bueno para insertar o agregar líneas basadas en una coincidencia que no distinga entre mayúsculas y minúsculas.
Tal vez las posibilidades se limitan a
FOO,Fooefoo. Estos pueden ser cubiertos porPara buscar todas las coincidencias posibles, se pueden usar expresiones entre corchetes para cada carácter:
fuente
La versión para Mac
sedparece un poco limitada. Una forma de evitar esto es usar un contenedor de Linux (a través de Docker) que tiene una versión utilizable desed:fuente
Si primero está haciendo una coincidencia de patrones, por ejemplo,
entonces quieres poner el
Idespués del patrón:Ejemplo:
devoluciones
willma; sin elI, devuelve la cadena sin tocar (Fred).fuente
sed: 1: "/fred/Is//willma/g": invalid command code Ised -r '/'"$PATTERN"'/I,${s//'$YELLOW'&'$NO_COLOR'/g;b};$q3'. Imprime el texto y, si se encuentra un patrón (que no distingue entre mayúsculas y minúsculas), resalta el texto en amarillo (color ansi). Si no se encuentra, devuelve el código de salida 3.Tenía una necesidad similar y se me ocurrió esto:
este comando para simplemente encontrar todos los archivos:
este para excluir this_shell.sh (en caso de que pones el comando en un script llamado this_shell.sh ), envía la salida a la consola para ver qué sucedió, y luego usa sed en cada nombre de archivo encontrado para reemplazar el texto foo con bar :
Elegí este método, ya que no me gustó que se cambiaran todas las marcas de tiempo de los archivos no modificados. alimentar el resultado de grep permite ver solo los archivos con el texto de destino (por lo tanto, es probable que también mejore el rendimiento / velocidad)
asegúrese de hacer una copia de seguridad de sus archivos y probarlos antes de usarlos. Es posible que no funcione en algunos entornos para archivos con espacios incrustados. (?)
fuente
Utilice lo siguiente para reemplazar todas las apariciones: sed 's / foo / bar / gI' mylog.txt
fuente
I. Tampoco creo que esto realmente responda a la pregunta, ya que no se refiere al reemplazo global.