¿Cómo utilizar un comando de shell para mostrar solo la primera columna y la última columna en un archivo de texto?

¿Cómo utilizar un comando de shell para mostrar solo la primera columna y la última columna en un archivo de texto?

Necesito ayuda para descubrir cómo usar el comando sed para mostrar solo la primera columna y la última columna en un archivo de texto. Esto es lo que tengo hasta ahora para la columna 1:

cat logfile | sed 's/\|/ /'|awk '{print $1}'

Mi débil intento de mostrar también la última columna fue:

cat logfile | sed 's/\|/ /'|awk '{print $1}{print $8}'

Sin embargo, esto toma la primera columna y la última columna y las combina en una lista. ¿Hay alguna manera de imprimir claramente la primera columna y la última columna con los comandos sed y awk?

Entrada de muestra:

foo|dog|cat|mouse|lion|ox|tiger|bar

Respuesta1

Casi llegamos. Simplemente coloque las referencias de ambas columnas una al lado de la otra.

cat logfile | sed 's/|/ /' | awk '{print $1, $8}'

También tenga en cuenta que no lo necesita cataquí.

sed 's/|/ /' logfile | awk '{print $1, $8}'

También tenga en cuenta que puede ver awkque los separadores de columnas son |, en lugar de espacios en blanco, por lo que no los necesita sed.

awk -F '|' '{print $1, $8}' logfile

segúnsugerenciasporcaleb, si desea una solución que aún genere el último campo, incluso si no hay exactamente ocho, puede usar $NF.

awk -F '|' '{print $1, $NF}' logfile

Además, si desea que la salida conserve los |separadores, en lugar de utilizar un espacio, puede especificar los separadores del campo de salida. Desafortunadamente, es un poco más complicado que simplemente usar la -Fbandera, pero aquí hay tres enfoques.

  • Puede asignar los separadores de campo de entrada y salida en awksí mismo, en el bloque BEGIN.

    awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
    
  • Puede asignar estas variables cuando llame awkdesde la línea de comando, a través de la -vbandera.

    awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
    
  • o simplemente:

    awk -F '|' '{print $1 "|" $8}' logfile
    

Respuesta2

Estás usando awkde todos modos:

awk '{ print $1, $NF }' file

Respuesta3

Simplemente reemplace del primero al último |con |(o espacio si lo prefiere):

sed 's/|.*|/|/'

Tenga en cuenta que, aunque no hay ninguna sedimplementación donde| sea especial (siempre queextendidolas expresiones regulares no están habilitadas a través -Ede -ralgunas implementaciones), \|en sí mismo es especial en algunas como GNU sed. Entonces deberíasnoescape |si desea que coincida con el |personaje.

Si reemplaza con espacio y si la entrada ya puede contener líneas con solo una |, entonces tendrá que tratar eso de manera especial ya que |.*|no coincidirá con esas. Eso podria ser:

sed 's/|\(.*|\)\{0,1\}/ /'

(es decir, hacer que la .*|parte sea opcional) O:

sed 's/|.*|/ /;s/|/ /'

o:

sed 's/\([^|]*\).*|/\1 /'

Si desea los campos primero y octavo independientemente de la cantidad de campos en la entrada, entonces es solo:

cut -d'|' -f1,8


(todos funcionarían con cualquier utilidad compatible con POSIX suponiendo que la entrada forme texto válido (en particular, sedgeneralmente no funcionarán si la entrada tiene bytes o secuencias de bytes que no forman caracteres válidos en la configuración regional actual, como por ejemplo printf 'unix|St\351phane|Chazelas\n' | sed 's/|.*|/|/'en una configuración regional UTF-8)).

Respuesta4

Parece que estás intentando obtener el primer y el último campo de texto que están delimitados por |.

Supuse que su archivo de registro contiene el texto como el siguiente,

foo|dog|cat|mouse|lion|ox|tiger|bar
bar|dog|cat|mouse|lion|ox|tiger|foo

Y quieres el resultado como,

foo bar
bar foo

Si es así, aquí viene el comando para el suyo.

A través de GNU sed,

sed -r 's~^([^|]*).*\|(.*)$~\1 \2~' file

Ejemplo:

$ echo 'foo|dog|cat|mouse|lion|ox|tiger|bar' | sed -r 's~^([^|]*).*\|(.*)$~\1 \2~'
foo bar

información relacionada