
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 cat
aquí.
sed 's/|/ /' logfile | awk '{print $1, $8}'
También tenga en cuenta que puede ver awk
que 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 -F
bandera, pero aquí hay tres enfoques.
Puede asignar los separadores de campo de entrada y salida en
awk
sí mismo, en el bloque BEGIN.awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
Puede asignar estas variables cuando llame
awk
desde la línea de comando, a través de la-v
bandera.awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
o simplemente:
awk -F '|' '{print $1 "|" $8}' logfile
Respuesta2
Estás usando awk
de 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 sed
implementación donde|
sea especial (siempre queextendidolas expresiones regulares no están habilitadas a través -E
de -r
algunas 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, sed
generalmente 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