3 votes

Comment obtenir des valeurs après un signe égal

J'ai un fichier délimité avec des espaces et un ordre aléatoire des colonnes comme suit :

name=Joan age=42 ip=172.20.1.80 sex=M loc=UK 
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra 

Je veux extraire des champs spécifiques ( name , loc und ip ) uniquement.

Le résultat que je cherche est donc le suivant :

Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1

4voto

PerlDuck Points 12079

Par chance, votre fichier d'entrée a un format que le Shell comprend lorsqu'il s'agit de d'attribuer une valeur aux variables : var1=value1 var2=value2 etc. Nous pouvons donc simplement lire chaque ligne et utiliser le eval pour évaluer la ligne.

Mettez ce qui suit dans un fichier, disons parse.sh , faire chmod +x parse.sh et l'exécuter avec votre fichier d'entrée comme paramètre.

script parse.sh :

#!/usr/bin/env bash

while read line; do
    eval $line;
    echo "$name|$loc|$ip"
done < "$1"

exit 0;

Fichier input.txt :

name=Joan age=42 ip=172.20.1.80 sex=M loc=UK
loc=IR sex=F ip=172.20.1.1 age=32 name=Sandra

Cours :

me@ubuntu:~> ./parse.sh input.txt 
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1

Veuillez noter que les valeurs ne doivent pas comporter d'espace. Par exemple

ip=... name=Ubai salih loc=...

ne fonctionnerait pas et donnerait des erreurs de syntaxe. De plus, si le fichier d'entrée contient une ligne avec un caractère bad_command cette commande est exécutée car c'est ainsi que eval fonctionne : elle exécute simplement la chaîne de caractères donnée.

1voto

wjandrea Points 13147

Pour info, voici une solution Python du genre La solution Bash de PerlDuck mais sans évaluer l'entrée.

#!/usr/bin/env python3

import fileinput

for line in fileinput.input():
    record = line.rstrip('\n')
    d = dict(kv.split('=') for kv in record.split(' '))
    print(d['name'], d['loc'], d['ip'], sep='|')

Cours :

$ ./parse.py input.txt
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1

0voto

steeldriver Points 118154

Puisque l'ordre de sortie que vous souhaitez est lexical inversé (name > loc > ip), vous pouvez sélectionner et trier les champs de manière inversée, puis supprimer l'élément de la liste. fieldname= préfixes. Par exemple, en Perl :

$ perl -alne '
    print join "|", map { s/.*=//r } reverse sort grep { /^(name|loc|ip)=/ } @F
' file
Joan|UK|172.20.1.80
Sandra|IR|172.20.1.1

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X