example comando bash unix grep cut

comando - Unix bash cutting y grep



cut lines linux command (6)

El método más fácil de hacer esto es mirar los resultados de grep

#!/bin/bash read -p "Enter title: " TITLE FILENAME="db.txt" IFS=$''/n'' for LINE in `grep -iw "Harry Potter" "$FILENAME"`; do echo $LINE | awk ''BEGIN { FS = ":" } ; { print $1, $2, $3, $4, $5 }'' done

El cambio IFS cambia el delimitador a una nueva línea en lugar de un espacio y el FS en el comando awk cambia el delimitador a: para permitir el acceso a los campos

Tengo un archivo de texto llamado db.txt. Algunas líneas de muestra del archivo son las siguientes:

Harry Potter y la piedra de hechicero: JK Rowling: 21.95: 100: 200

Harry Potter y la Cámara de los Secretos: JK Rowling: 21.95: 150: 300

El señor de los anillos, La comunidad del anillo: JRR Tolkien: 32.00: 500: 500

Un juego de tronos: George RR Martin: 44.50: 300: 250

Luego en mi script, tengo las siguientes líneas:

echo "Enter title:" read TITLE cut -d ":" -f 1 db.txt | grep -iw "$TITLE" | while read LINE do STRING="`echo $LINE | cut -d ":" -f 1`," STRING="$STRING `echo $LINE | cut -d ":" -f 2`, " STRING=" /$$STRING`echo $LINE | cut -d ":" -f 3`," STRING=" $STRING`echo $LINE | cut -d ":" -f 4`," STRING=" $STRING`echo $LINE | cut -d ":" -f 5`" done

¿Hay alguna manera de grep un campo específico de corte y luego pasar en la línea completa en el ciclo while?

Por ejemplo, si ingresé "Harry Potter", debería mostrar:

Harry Potter y la piedra de brujo, JK Rowling, $ 21.95, 100, 200

Harry Potter y la Cámara de los Secretos, JK Rowling, $ 21.95, 150, 300


El siguiente paso desde grep y cut es awk . A menos que tengas que hacer esto usando bash (¿es esta tarea?), Entonces awk facilitaría mucho las cosas:

awk -F: ''/harry potter/ { sub(/^/,"$",$(NF-2)); print }'' IGNORECASE=1 OFS=", " db.txt

Entrada de prueba:

Harry Potter and the Sorcerer''s Stone:J.K. Rowling:21.95:100:200 Harry Potter and the Chamber of Secrets:J.K. Rowling:21.95:150:300 Lord of the Rings, The Fellowship of the Ring:J.R.R. Tolkien:32.00:500:500 A Game of Thrones:George R.R. Martin:44.50:300:250

Prueba de salida:

Harry Potter and the Sorcerer''s Stone, J.K. Rowling, $21.95, 100, 200 Harry Potter and the Chamber of Secrets, J.K. Rowling, $21.95, 150, 300


Puede hacer esto sin cut , y sin grep si está bien con la coincidencia de expresión regular de bash (o puede usar la coincidencia de patrón de shell en su lugar).

La idea sería leer el archivo línea por línea, luego dividir la línea en una matriz. Una vez que tenga eso, haga las comparaciones y la producción que desee.

Aquí hay una demostración de la técnica:

#! /bin/bash echo "Title:" read title # shopt -s nocasematch # if you want case-insensitive matching while read line ; do # this read takes data from input.txt, see # end of loop IFS=: read -a parts <<< "$line" # this splits the line on ":" into # an array called parts if [[ ${parts[0]} =~ $title ]] ; then # regex matching printf "%s -- %s/n" "${parts[1]}" "${parts[2]}" fi done < input.txt


Si puedes usar sed esto sería una solución

read -p "Enter title: " TITLE sed -n -e ''s/^/([^:]/+:/)/{2/}//0$/'' -e ''s/:/, /g'' -e "/^$TITLE/Ip" db.txt

Breve explicación de lo que hace

-n tells sed not to print any lines -e ''s/^/([^:]/+:/)/{2/}//0$/'' matches for the 2nd : and adds a $ after it -e ''s/:/, /g'' replaces all : with , and a following whitespace -e "/^$TITLE/Ip" tells sed to print all lines which start with $TITLE (that''s the p) and I tells sed to match case-insensitive


read -p "Enter title: " TITLE while IFS=: read title author price x y; do if [[ ${title,,} == *${TITLE,,}* ]]; then printf "%s, %s, $%s, %s, %s/n" "$title" "$author" "$price" "$x" "$y" fi done < db.txt

La prueba en el comando if hace un simple emparejamiento global, pero insensiblemente, por lo que coincidirá si el usuario ingresa "potter".

O bien, use sed para cambiar los separadores:

read -p "Enter title: " TITLE sed ''/''"$TITLE"''/I!d; s/:/, /g'' db.txt

lo que significa que elimina todas las líneas que no coinciden con el TÍTULO, luego transforma el separador.


Sé que no lo especificó, pero awk es probablemente la mejor herramienta para usar en esta tarea. Combina cut, sed y grep en una herramienta práctica y fácil de usar. Bueno, una herramienta conveniente ...

Para entender awk , debes entender algunas cosas:

  • Awk es un lenguaje de programación. Ha construido en lógica y variables.
  • Awk supone un ciclo de lectura que lee todas y cada una de las líneas.
  • Los programas Awk deben estar rodeados de llaves.
  • No solo las llaves, sino que las variables de análisis de Awk comienzan con signos de dólar. Por lo tanto, debe poner sus programas Awk rodeados por comillas simples para mantener el shell fuera de él.
  • Awk analiza automáticamente cada línea en función del separador de campo . El separador de campo predeterminado es un espacio de tiempo, pero puede cambiarlo a través del parámetro -f .
  • Cada campo obtiene una variable especial. El primer campo es $1 , el siguiente campo es $2 , etc. Toda la línea es $0 .

Aquí está tu declaración de Awk:

awk -F: ''{ title = $1 author = $2 price = $3 pages_read_until_i_got_bored=$4 pages = $5 print "I read " pages_read_until_i_gob_bored "pages out of " $pages " pages of " $title " by " $author "." }'' $file

Por supuesto, todo el asunto podría ser una sola línea también:

awk -F: ''{ print "I read " $4 " pages " out of " $5 " of " $1 " by " $2 "." }'' $file

Solo quería enfatizar la programabilidad de Awk y cómo se puede usar para hacer este tipo de análisis.

Si su pregunta es cómo ingresar esta información y ponerla en variables de entorno, la respuesta de Glenn Jackman es la mejor.