Tengo un archivo algo como:
helsoidfiejoih
heye heye hey
me is hi
El archivo puede tener cualquier cantidad de líneas o caracteres, el punto es que es un archivo de texto de algún tipo. Ahora necesito usar grep para realizar alguna operación de modo que el primer parámetro pasado a grep sea el nombre del archivo y el segundo parámetro sea el patrón. Pero grep hace una coincidencia codiciosa por lo que coincide con toda la línea en lugar de una coincidencia no codiciosa que es lo que quiero (coincidencia no codiciosa). Ahora lo intenté:
grep -Ec -Po "$2" $1
Me da expresiones contradictorias. Y el usuario puede ingresar cualquier patrón, también conocido como RE, por lo que -E es una opción necesaria. ¿Hay alguna manera de hacer que grep no sea codicioso? Me dijeron que la opción -P hace que el comando grep no sea codicioso, pero después de probarlo:
grep -c -Po "$2" $1
¿No parece que la expresión grep no sea codiciosa?
Editar: La gente dijo que no estoy mostrando los patrones con los que trabajo, así que para aclarar los patrones será un RE, por ejemplo, si el usuario ingresa
./thisfile.sh h file1.txt
Encontrará el número de veces que h aparece en el archivo 1.txt si el usuario ingresa
./thisfile.sh io file1.txt
Encontrará la cantidad de veces que aparece io en el archivo 1.txt. ¿Hay alguna forma de hacer esto?
Respuesta1
Para contar cuántas veces aparece una subcadena en un archivo:
#!/bin/sh
grep -F -o -e "$1" | wc -l
Usarías este script así:
$ ./script e <script
2
$ ./script ' -' <script
4
$ ./script hey <file1
3
$ ./script he <file1
4
$ df | ./script %
7
Aquí estoy contando la cantidad de e
caracteres en el script en sí y luego la cantidad de veces que aparece la subcadena que consta de un espacio y un guión en el script. Luego cuento un par de subcadenas en el archivo presentado en la pregunta. El último ejemplo cuenta el número de signos de porcentaje en la salida de df
mi sistema.
Los datos de entrada se leen a través de la entrada estándar y el único argumento del script es la subcadena que queremos buscar y contar.
El script consta de un único canal grep
+ . wc
Utiliza la -o
opción no estándar (pero comúnmente implementada) para devolver una lista de coincidencias que no se superponen en líneas separadas. Estas líneas luego se cuentan con wc -l
.
La llamada a grep
utiliza -F
para hacer que el patrón se interprete como una cadena y no como una expresión regular. Esto hace posible contar el número de veces que, por ejemplo, *
ocurre en un archivo, sin tener que escapar del *
(aún tendrías que hacerlo).cita(Sin embargo, para *
evitar que el caparazón lo use como un patrón globular). Omítelo -F
si desea utilizar el patrón como expresión regular.
La -e
opción se utiliza para indicar grep
cuál $1
es el patrón. Si -e
no se utiliza, un patrón como --version
se interpretaría como una opción para grep
.
Respuesta2
Algunas versiones de grep
(por ejemplo, GNU) le permiten proporcionar RE compatibles con Perl (consultePCRE), son mucho más flexibles que las expresiones regulares POSIX estándar.