it-swarm.com.de

Verwenden Sie bash, um die Zahl in eckigen Klammern zu extrahieren

Meine Datei sieht so aus:

[581]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);  
[50]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);

Jede neue Zeile beginnt mit dem Muster [number]. Jede Zeile endet mit dem Muster );.

Ich muss die Zahlen in eckigen Klammern am Anfang jeder Zeile extrahieren und in eine neue Datei schreiben. Ich weiß vorher nicht, wie viele Zeilen die Datei enthält.

3
user3069326

Sie können dies mit nur einem einzigen grep Befehl erreichen. Dies liegt daran, dass Sie mit GNU grep einen regulären Perl-Ausdruck (-P) verwenden können, der Lookaround-Aussagen mit Null-Breite (\K und (?=), in diesem Fall):

grep -oP '^\[\K\d+(?=\])' infile

Dadurch wird die Ausgabe wie beschrieben an Ihr Terminal gesendet. Um es in eine Datei umzuleiten, verwenden Sie:

grep -oP '^\[\K\d+(?=\])' infile > outfile

Diese Methode hat den Vorteil der Kürze und Einfachheit. Es stimmt mit dem Text überein

  • wird vorangestellt von (\K)

    • ein [ -Zeichen (\[) - \ wird benötigt, da [ ansonsten in regulären Ausdrücken eine besondere Bedeutung hat
    • das erscheint am Anfang einer Zeile (^);
  • besteht aus einer oder mehreren (+) Ziffern (\d);

  • wird gefolgt von ((?=))

    • ein ] -Zeichen (\]) - wie bei [, \ zwingt ], wörtlich abgeglichen zu werden.
12
Eliah Kagan

sed verwenden:

  • < inputfile sed -n 's/^\[\([0-9]*\)\].*$/\1/p' > out

Befehlsaufschlüsselung :

  • < inputfile: Leitet den Inhalt von inputfile zu stdin um
  • -n: Unterdrückt die Ausgabe
  • > out: Leitet den Inhalt von stdout zu out um

Regex-Aufschlüsselung :

  • s: Führt eine Ersetzung durch
  • /: Startet den regulären Ausdruck
  • ^: Entspricht dem Zeilenanfang
  • \[: Entspricht einem [ -Zeichen
  • \(: Startet die Erfassungsgruppe
  • [0-9]*: Stimmt mit einer beliebigen Anzahl von Ziffern überein
  • \): Stoppt die Aufnahmegruppe
  • \]: Entspricht einem ] -Zeichen
  • .*: Stimmt mit einer beliebigen Anzahl von Zeichen überein
  • $: Entspricht dem Zeilenende
  • /: stoppt den regulären Ausdruck/startet den Austausch
  • \1: Ersetzt durch die erste Erfassungsgruppe
  • /: Stoppt den Austausch
  • p: druckt nur die übereinstimmenden Zeilen

Verwenden von grep + tr (wenn Sie eine Methode benötigen, die sowohl auf Ubuntu als auch auf einem anderen Betriebssystem ausgeführt wird, dessen grep PCRE nicht unterstützt) - ansonsten lesen Sie Eliah Kagan's) grep- Nur Version ):

  • < inputfile grep -o '^\[[0-9]*\]' | tr -d '[]' > out

Befehlsaufschlüsselung :

  • < inputfile in grep: Leitet den Inhalt von inputfile zu stdin um
  • -o in grep: druckt nur die Übereinstimmung
  • -d in tr: löscht die Zeichen
  • > out in tr: Leitet den Inhalt von stdout zu out um

Regex-Aufschlüsselung :

  • ^: Entspricht dem Zeilenanfang
  • \[: Entspricht einem [ -Zeichen
  • [0-9]*: Stimmt mit einer beliebigen Anzahl von Ziffern überein
  • \]: Entspricht einem ] -Zeichen
7
kos

der Perl Weg:

Perl -ne 'print "$1\n" if /^\[([0-9]*)\].*/' testdata > out

oder mit awk:

awk 'match($0, /^\[[0-9]*\]/) {print substr($0, RSTART + 1, RLENGTH - 2)}' testdata > out

In beiden Fällen verwendete Regex:

^\[[0-9]*\]

Erläuterung

  • /^\[[0-9]*\]/

    • ^ Position am Anfang der Zeichenkette bestätigen

    • \[ stimmt wörtlich mit dem Zeichen [ überein

    • [0-9]* stimmt mit einem einzelnen Zeichen in der folgenden Liste überein

      • Quantifier: * Zwischen null und unbegrenzt oft, so oft wie möglich, nach Bedarf zurückgeben [gierig]

      • 0-9 Ein einzelnes Zeichen im Bereich zwischen 0 und 9

    • \] stimmt wörtlich mit dem Zeichen ] überein

    Regular expression visualization
    (Quelle: debuggex.com )

    Debuggex Demo

3
A.B.

Verwenden Sie dies in Bash:

 grep -oh '\[[0-9].*\]' mytestfile | sed 's/.*\[\([^]]*\)\].*/\1/g' > myresultfile
2
Frantique

python Lösung mit re Modul und unter Berücksichtigung von zwei Situationen:

#!/usr/bin/env python2
import re
with open('/path/to/file.txt') as f:
    for line in f:
        digits_case_1 = re.search(r'(?<=^\[)\d+(?=\])', line)
        digits_case_2 = re.search(r'(?<=^\[)\d+(?=\].*\);$)', line)
        if digits_case_1:
            print 'Not considering ");" at end: ' + digits_case_1.group()
        if digits_case_2:
            print 'Considering ");" at end: ' + digits_case_2.group()

Ausgabe:

Not considering ");" at end: 581
Not considering ");" at end: 50
Considering ");" at end: 50

Hier habe ich zwei Situationen betrachtet, da mir Ihre Frage nicht klar erscheint.

  • digits_case_1 gibt die Ziffernübereinstimmung zwischen [] am Zeilenanfang aus. Dabei wird nicht berücksichtigt, ob die Zeile mit ); endet oder nicht.

  • digits_case_2 gibt nur dann Ziffern zwischen [] am Zeilenanfang aus, wenn die Zeile mit ); endet.

1
heemayl

cat $FILE | awk -F\] '{ print $1 }' | grep '\[' | tr -d '['

Wo der Fortschritt ist:§

$ FILE=/tmp/tmp.tmp

$ cat $FILE
[581]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
[50]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);

$ cat $FILE | awk -F\] '{ print $1 }'
[581
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
[50

$ cat $FILE | awk -F\] '{ print $1 }' | grep '\['
[581
[50

$ cat $FILE | awk -F\] '{ print $1 }' | grep '\[' | tr -d '['
581
50

$

§ Für diejenigen ohne Zugriff auf den Befehl man.

0
boardrider