J'ai un ensemble de données en entrée et j'ai besoin de l'avant-dernier champ basé sur le délimiteur. Les lignes peuvent avoir différents nombres de délimiteurs. Comment obtenir l'avant-dernier champ?
exemple d'entrée
text,blah,blaah,foo
this,is,another,text,line
production attendue
blaah
text
Vous avez un indice de coupe Unix sauf les deux derniers jetons et capable de comprendre la réponse:
cat datafile | rev | cut -d '/' -f 2 | rev
Awk convient bien à cela:
awk -F, '{print $(NF-1)}' file
La variable NF est une variable awk spéciale qui contient le nombre de champs dans l'enregistrement en cours.
Il n'est pas nécessaire d'utiliser cut
, rev
ou tout autre outil externe à bash ici. Il suffit de lire chaque ligne dans un tableau et de choisir la pièce que vous souhaitez:
while IFS=, read -r -a entries; do
printf '%s\n' "${entries[${#entries[@]} - 2]}"
done <file
Faire cela en pure bash est beaucoup plus rapide que de démarrer un pipeline, au moins pour des entrées raisonnablement petites. Pour les grandes entrées, le meilleur outil est awk.
Solution Perl similaire à la solution awk de @iiSeymour
Perl -lane 'print $F[-2]' file
Ces options de ligne de commande sont utilisées:
n
boucle autour de chaque ligne du fichier d'entrée, n'imprime pas automatiquement chaque ligne
l
supprime les sauts de ligne avant le traitement et les réintègre ensuite
a
mode autosplit - divise les lignes d'entrée dans le tableau @F. Par défaut, la division sur un espace blanc
e
exécute le code Perl
Le @F
le tableau autosplit commence à l'index [0] tandis que les champs awk commencent par $ 1-1
est le dernier élément-2
est l'avant-dernier élément
Code pour GNU sed :
$ echo text, blah, blaah, foo | sed -r 's/^ (\ S +,) {2} (\ S +),. */\ 2 /' blaah $ echo this, is, another, text, line | sed -r 's/^ (\ S +,) {2} (\ S +),. */\ 2 /' texte
Exemple de code similaire à awk
code de Sudo_O:
$ sed -r 's /.*, (\ w +),\w + $/\ 1 /' fichier blaah texte
Il pourrait être préférable d'utiliser des programmes plus spécialisés pour les fichiers CSV
, par exemple. awk ou Excel .
cuts
:$ cat file.txt
text,blah,blaah,foo
this,is,another,text,line
$ cuts -2 file.txt
blaah
text
coupes , qui signifie "coupe sur les stéroïdes":
- automatically figures out the input field separators
- supports multi-char (and regexp) separators
- automatically pastes (side-by-side) multiple columns from multiple files
- supports negative offsets (from end of line)
- has good defaults to save typing + allows the user to override them
et beaucoup plus.
J'ai écrit cuts
après avoir été frustré par les trop nombreuses limitations de cut
sur Unix. Il est conçu pour remplacer divers combos cut
/paste
, le découpage et le découpage en colonnes de plusieurs fichiers, avec de multiples variantes de séparateur, tout en imposant une frappe minimale de la part de l'utilisateur.
Vous pouvez obtenir cuts
(logiciel gratuit, licence artistique) sur github: https://github.com/arielf/cuts/
L'appel de cuts
sans arguments affichera un message détaillé de Usage
.