J'ai besoin d'aide pour comprendre comment utiliser la commande sed pour n'afficher que la première et la dernière colonne d'un fichier texte. Voici ce que j'ai jusqu'à présent pour la colonne 1:
cat logfile | sed 's/\|/ /'|awk '{print $1}'
Ma faible tentative pour que la dernière colonne s'affiche également était:
cat logfile | sed 's/\|/ /'|awk '{print $1}{print $8}'
Cependant, cela prend la première colonne et la dernière colonne et les fusionne dans une liste. Existe-t-il un moyen d'imprimer clairement la première et la dernière colonnes avec les commandes sed et awk?
Exemple d'entrée:
foo|dog|cat|mouse|lion|ox|tiger|bar
Presque là. Placez simplement les deux références de colonne l'une à côté de l'autre.
cat logfile | sed 's/|/ /' | awk '{print $1, $8}'
Notez également que vous n'avez pas besoin de cat
ici.
sed 's/|/ /' logfile | awk '{print $1, $8}'
Notez également que vous pouvez dire à awk
que les séparateurs de colonnes sont |
, au lieu de blancs, vous n'avez donc pas besoin de sed
non plus.
awk -F '|' '{print $1, $8}' logfile
Selon suggestions par Caleb , si vous voulez une solution qui génère toujours le dernier champ, même s'il n'y en a pas exactement huit, vous pouvez utiliser $NF
.
awk -F '|' '{print $1, $NF}' logfile
De plus, si vous souhaitez que la sortie conserve le |
séparateurs, au lieu d'utiliser un espace, vous pouvez spécifier les séparateurs de champ de sortie. Malheureusement, c'est un peu plus maladroit que d'utiliser simplement le -F
flag, mais voici trois approches.
Vous pouvez affecter les séparateurs de champs d'entrée et de sortie dans awk
lui-même, dans le bloc BEGIN.
awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
Vous pouvez affecter ces variables lors de l'appel de awk
depuis la ligne de commande, via le -v
drapeau.
awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
ou simplement:
awk -F '|' '{print $1 "|" $8}' logfile
Vous utilisez quand même awk
:
awk '{ print $1, $NF }' file
Remplacez simplement du premier au dernier |
avec un |
(ou espace si vous préférez):
sed 's/|.*|/|/'
Notez que bien qu'il n'y ait pas d'implémentation de sed
où |
est spécial (tant que étend les expressions régulières ne sont pas activées via -E
ou -r
dans certaines implémentations), \|
lui-même est spécial dans certains comme GNU sed
. Vous devriez donc pas échapper |
si vous voulez qu'il corresponde au |
personnage.
Si le remplacement par un espace et si l'entrée peut déjà contenir des lignes avec un seul |
, alors, vous devrez traiter cela spécialement comme |.*|
ne correspondra pas à ceux-ci. Cela pourrait être:
sed 's/|\(.*|\)\{0,1\}/ /'
(c'est-à-dire faire le .*|
partie facultative) Ou:
sed 's/|.*|/ /;s/|/ /'
ou:
sed 's/\([^|]*\).*|/\1 /'
Si vous voulez les premier et huitième champs quel que soit le nombre de champs dans l'entrée, alors c'est juste:
cut -d'|' -f1,8
(tous ceux-ci fonctionneraient avec n'importe quel utilitaire compatible POSIX en supposant que le texte d'entrée des formulaires est valide (en particulier, les sed
ne fonctionneront généralement pas si l'entrée contient des octets ou des séquences d'octets qui ne forment pas de caractères valides dans le locale actuelle comme par exemple printf 'unix|St\351phane|Chazelas\n' | sed 's/|.*|/|/'
dans un environnement local UTF-8)).
Si vous vous retrouvez sans gêne ni séduction, vous pouvez réaliser la même chose avec coreutils:
paste <( cut -d'|' -f1 file) \
<(rev file | cut -d'|' -f1 | rev)
Il semble que vous essayez d'obtenir les premier et dernier champs de texte délimités par |
.
J'ai supposé que votre fichier journal contient le texte ci-dessous,
foo|dog|cat|mouse|lion|ox|tiger|bar
bar|dog|cat|mouse|lion|ox|tiger|foo
Et vous voulez la sortie comme,
foo bar
bar foo
Si oui, alors voici la commande pour la vôtre
Par GNU sed,
sed -r 's~^([^|]*).*\|(.*)$~\1 \2~' file
Exemple:
$ echo 'foo|dog|cat|mouse|lion|ox|tiger|bar' | sed -r 's~^([^|]*).*\|(.*)$~\1 \2~'
foo bar
Vous devriez probablement le faire avec sed
- je le ferais quand même - mais, juste parce que personne n'a encore écrit celui-ci:
while IFS=\| read col1 cols
do printf %10s%-s\\n "$col1 |" " ${cols##*|}"
done <<\INPUT
foo|dog|cat|mouse|lion|ox|tiger|bar
INPUT
foo | bar