2016-04-04 5 views
0

Ich habe mehrere Strings, die das folgende Format ähnlich sind:Extrahieren zwei Werte aus einer Linie mit regex in Bash-Skript

Hallo zusammen Andre (91234342), die derzeit zeigen unsere Daten, dass am 2016.10.24 Sie wurden gefunden ...

ich brauche die Zahl in Klammern zu extrahieren sowohl die immer eine 8-stellige Nummer und das Datum, die immer im YYYY-MM-DD Format ist. Sie erscheinen jedoch nicht immer in der gleichen Reihenfolge in der Zeichenfolge.

Der Ausgang muss wie folgt aussehen: 2016-10-24 91234342

ich versucht habe sed mit den Werten bekommen ich will, aber kann nur verwalten einen Wert erhalten sed verwenden.

Kann jemand Hilfe/Beratung anbieten?

Vielen Dank!

+0

sollten Sie zu leistungsfähigeren Optionen wie 'perl' wechseln, da es immer schwieriger wird, wenn die Anzahl der zu erfassenden Gruppen steigt – rock321987

+0

@ rock321987 sed ist in Ordnung für diese ... – 123

+0

@ 123 das ist, warum ich gesagt habe, wenn die Anzahl der Gruppen steigt – rock321987

Antwort

1

verwenden nur 2 Ausdrücke beiden Formate der Bestellung wie diese zu erfüllen:

$ cat file 
Hi there Andre (91234342), currently our records show that on 2016-10-24 you were found ... 
Hi there Andre 2016-10-24, currently our records show that on (91234342) you were found ... 
$ sed -r -e 's/^.*\(([0-9]{8})\).*([0-9]{4}-[0-9]{2}-[0-9]{2}).*$/\2 \1/' -e 's/^.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*\(([0-9]{8})\).*$/\1 \2/' file 
2016-10-24 91234342 
2016-10-24 91234342 
$ 

dies ist der erste Ausdruck für Zeile nach 8-stellige Nummer mit Datum:
-e 's/^.*\(([0-9]{8})\).*([0-9]{4}-[0-9]{2}-[0-9]{2}).*$/\2 \1/'

und dieser Ausdruck ist für die umgekehrte Reihenfolge:
-e 's/^.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*\(([0-9]{8})\).*$/\1 \2/'

+1

Warum ist das "G" notwendig? Warum ist der Bindestrich ('\ -') ausgeblendet? –

+0

@ DavidC.Rankin ja es ist nicht notwendig .. repariert es thnx – ritesht93

0

Versuchen Sie folgendes:

sed -r 's/.*\(([0-9]{8})\).*([0-9]{4}-[0-9]{2}-[0-9]{2}).*/\2 \1/;s/.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*\(([0-9]{8})\).*/\1 \2/' infile 
0

Nach regex sollte funktionieren

.+\((\d{8})\).+(\d{4}\-\d{2}\-\d{2}).+ 
0

Sie haben mehrere Möglichkeiten. Die anderen Antworten haben bereits die Verwendung von erweiterten regulären Ausdruck Syntax gezeigt, aber Sie können auch reguläre Ausdrücke mit einer leichten Anpassung der Syntax verwenden, und Sie können ein kurzes Skript erstellen, um wiederholte Eingabe zu beseitigen.

Zum Beispiel grundlegende Syntax wäre:

$ sed -e "s/^.*[(]\([0-9]\{8\}\)[)].*\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*$/\2 \1/; 
s/^.*\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*[(]\([0-9]\{8\}\)[)].*$/\1 \2/" file.txt 

Beispiel datei.txt

$ cat file.txt 
Hi there Andre (91234342), currently our records show that on 2016-10-24 you were found ... 
Hi there Andre 2016-10-24, currently our records show that on (91234342) you were found ... 

den regulären Ausdruck oben gibt:

2016-10-24 91234342 
2016-10-24 91234342 

Verwenden von Variablen innerhalb eines Skript

Sie können Variablen verwenden, um den regulären Ausdruck beizubehalten und den Befehl zu ersetzen.Zum Beispiel:

#!/bin/bash 

digits='[(]\([0-9]\{8\}\)[)]' 
pdate='\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)' 

sed -e "s/^.*${digits}.*${pdate}.*$/\2 \1/; 
s/^.*${pdate}.*${digits}.*$/\1 \2/" \ 
"$1" 

Ausgabe

$ bash sedcmd.sh file.txt 
2016-10-24 91234342 
2016-10-24 91234342 

So oder so, mit regelmäßiger oder erweiterte Syntax, finden nur einen Weg um den Ausdruck zu speichern, damit Sie müssen es nicht erneut eingeben riskieren :)

Verwandte Themen