web-dev-qa-db-fra.com

Recherche ligne par ligne de texte entre les deux premières correspondances

J'ai le fichier avec le texte:

1861_ASSET-D_T_201702181000-201702181045_HN_
197895_STRING-H_T_201702181000-201702181045_HN_
14512861_FILE-FD_T_201702181000-201702181045_HN

Comment puis-je affecter du texte entre les première et deuxième correspondances "_" en utilisant egrep, awk ou sed?

Je veux avoir:

ASSET-D
STRING-H
FILE-FD
6
Oleksii

Vous pouvez utiliser awk avec les paramètres suivants:

  • -F "_" - qui utilise _ comme séparateur
  • '{print $2}' - qui imprime le 2e élément

    $ awk -F  "_" '{print $2}' input_file
    ASSET-D
    STRING-H
    FILE-FD
    
10
Yaron
$ sed -r 's/[^_]+_([^_]+)_.*/\1/' file
ASSET-D
STRING-H
FILE-FD

Explication

  • -r Utilisez ERE
  • s/old/new/ remplace old par new
  • [^_]+ certains caractères non soulignés
  • (some chars) enregistrer some chars pour plus tard
  • .* un nombre quelconque de caractères
  • \1 le motif enregistré
10
Zanna

Si vous voulez autoriser d'autres outils, cut serait la solution la plus simple:

cut -d _ -f 2 < input.txt > output.txt
9
David Foerster

Quelques approches Perl:

$ Perl -F_ -lae 'print $F[1]' file 
ASSET-D
STRING-H
FILE-FD

Le -a fait agir Perl comme un awk, scindant chaque ligne d'entrée sur le caractère donné par -F et sauvegardant chaque champ résultant dans le tableau @F. Par conséquent, l’impression $F[1] imprimera le deuxième champ (les tableaux commencent à compter à 0).

Alternativement:

$ Perl -pe 's/.*?_(.+?)_.*/$1/' file 
ASSET-D
STRING-H
FILE-FD

Le -p signifie "imprime chaque ligne d’entrée après avoir exécuté le script donné par -e dessus". Le s/from/to/ est l'opérateur de substitution. Il remplacera from par to. Ici, je fais correspondre 0 ou plusieurs caractères (.*) mais en le rendant "non glouton" (.*?); que ? le fait s'arrêter à la correspondance la plus courte possible. Par conséquent, .*?_ fera correspondre tout jusqu'au 1er _. La partie suivante, (.+?)_ correspond à un ou plusieurs caractères jusqu'au prochain _, puis tout le reste jusqu'à la fin de la ligne (.*). Les parenthèses "capturent" la correspondance et la rendent disponible dans la partie de remplacement de l'opérateur sous la forme $1. Par conséquent, le tout va simplement remplacer la ligne entière par ce qui était entre parenthèses.


Vous pouvez aussi simplement faire ceci avec grep:

$ grep -oP '^.*?_\K[^_]+' file 
ASSET-D
STRING-H
FILE-FD

-o signifie "n'imprime que la partie de chaque ligne correspondant" et -P active les expressions régulières compatibles Perl (PCRE) qui nous donnent \K. Le \K, à son tour, signifie "ignorer tout ce qui correspond jusqu'à ce point". Cela signifie que nous pouvons utiliser le ^.*?_ pour tout aligner jusqu'au premier _, puis utiliser \K pour le supprimer afin qu'il ne soit pas imprimé. Ensuite, il nous faut juste autant de caractères non -_ que nous pouvons trouver ([^_]+).

6
terdon

En tant que python one-liner:

python3 -c "[print(l.split('_')[1]) for l in open('f')]"

'f' est votre fichier, entre guillemets, par exemple:

python3 -c "[print(l.split('_')[1]) for l in open('/home/jacob/blub')]"

ASSET-D
STRING-H
FILE-FD

Explication

for l in open('f')

lit f par ligne, et

l.split('_')[1]

divise la ligne par le délimiteur _, conserve la deuxième chaîne (index [1], où [0] est la première).

print(l.split('_')[1]) 

imprime ensuite la chaîne trouvée.

6
Jacob Vlijm