Suchen Sie nach einer Reihe von Zeilen von $START bis $END AND, die eine Übereinstimmung im $MIDDLE enthält.

Suchen Sie nach einer Reihe von Zeilen von $START bis $END AND, die eine Übereinstimmung im $MIDDLE enthält.

Grep/Awk/Sed für eine Reihe von Zeilen von "0010|" bis "0070|" UND die eine Übereinstimmung in $PH_NO enthält

Unten sind die Beispieldaten. Ich muss nach der Telefonnummer suchen, die im Feld 0012 vorhanden ist, und nach den entsprechenden vollständigen Kundendatensätzen, Zeilen von 0010 bis 0070. Eine Datendatei kann zwei oder drei Kundendatensätze mit derselben Telefonnummer enthalten und ich muss sie alle abrufen.

0010|Kumar||57 Rich street|Chennai|Tamil Nadu|
0011|20171115| ID
0012|149 196 222| PH Number 
0013|20161101|20171102|
0022|Payment Method |Lucky customer|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|TP|10.00-|||
0070|000AYDCHDFF|820|762|
0010|RAM||57 Rich street|Chennai|Tamil Nadu|
0011|20171115| ID
0012|149 196 333| PH Number 
0013|20161101|20171102|
0022|Payment Method |Lucky customer|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|TP|10.00-|||
0070|000AYDCHDFF|820|762|
0010|Joe||57 Rich street|Chennai|Tamil Nadu|
0011|20171115| ID
0012|149 196 222| PH Number 
0013|20161101|20171102|
0022|Payment Method |Lucky customer|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|P|5.00-|20161111|Payment|
0080|P|5.00-|20161130|Payment|
0080|TP|10.00-|||
0070|000AYDCHDFF|820|762|

Hinweis: Ich bin auf einem AIX-Server mit ksh.

Antwort1

Sie möchten also den gesamten Datensatz von 0010 bis 0070, sofern die PH-Nummer übereinstimmt ? Dann funktioniert $PH_NO"dieser Einzeiler:sed

sed "/^0010/,/^0070/H;/^0010/h;/^0070/! d;x;/|$PH_NO| PH Number/! d"
  • /^0010/,/^0070/Hum einen Datensatz von 0010 bis 0070 an den Haltebereich anzuhängen
  • /^0010/hdie 0010 soll nicht angehängt werden, sondern einen neuen Datensatz beginnen, also kopiere sie in den Hold Space
  • /^0070/! dkeine weitere Verarbeitung oder Ausgabe, es sei denn, es handelt sich um das Element 0070
  • x;/|$PH_NO| PH Number/! d"Tauschen Sie die Leerzeichen aus, sodass sich der gesamte Datensatz nun im Musterbereich befindet, und löschen Sie ihn, wenn er die besagte Nummer nicht enthält.

Antwort2

for r in `grep -n '^0010\|^0012\|^0070' CUSTOMER_FILE | grep -C1 '[0-9]\+:0012|149 196 222|' | grep -o '^[0-9]\+' | paste -d, - - - | sed 's/,[0-9]\+,/,/g'`; do sed -n "$r"p CUSTOMER_FILE; echo; done

149 196 222im obigen Befehl ist die Telefonnummer des Kunden. Ändern Sie sie in die Telefonnummer, die Sie herausfinden möchten.

CUSTOMER_FILEist die Datei, nach der Sie suchen möchten. Ändern Sie sie in Ihren Dateinamen.

Sie können den Code auch in ein Bash-Skript einfügen und 149 196 222durch $1und durch ersetzen CUSTOMER_FILE. $2Sagen wir find-customer.sh, dann können Sie das Skript wie folgt ausführen

./find-customer.sh '149 196 222' your-file-name

Voraussetzung dieses Codestücks:

  1. Bash, GNU-Umgebung (GNU grep, GNU sed)
  2. Ihre Datei muss dem unten stehenden Format entsprechen 0010 ... <no 0010 or 0012 or 0070> ... 0012 ... <no 0010 or 0012 or 0070> ... 0070 ... <repeated content as above or end of file>


AKTUALISIEREN

Dies ist eine Hochleistungsversion. (Zumindest höher als die oben genannte Originalversion. Es ist überhaupt keine For-Schleife beteiligt.)

grep -n '^0010\|^0012\|^0070' CUSTOMER_FILE | grep -C1 '[0-9]\+:0012|149 196 222|' | grep -o '^[0-9]\+' | paste -d, - - - | sed -r 's|([0-9]+),[0-9]+,([0-9]+)|\1,\2p;\2a|g' | sed -n -f - CUSTOMER_FILE


UPDATE für AIX

Da der Fragesteller unter AIX arbeitet, unterstützt das Grep unter AIX die Kontextoptionen -A, -B und -C nicht.

Im Internet gibt es eine Vielzahl von "cgrep" (context grep)-Implementierungen, um dieses Problem zu lösen (um die GNU grep-Kontextoption zu simulieren). Die meisten davon können jedoch nicht dieselbe Ausgabe wie GNU grep liefern. Nur eine, die ich gefunden habe, kommt der GNU grep-Kontextoption am nächsten. Der Link isthttps://stackoverflow.com/questions/1685678/advanced-grep-unix/1685782#1685782

Ich habe für diesen Fall einige notwendige Änderungen vorgenommen.

#!/bin/bash
BEFORE=$1
AFTER=$1
FILE=/tmp/.cattmp
PATTERN="$2"
cat > $FILE
for i in $(grep -n "$PATTERN" $FILE | sed -e 's/\:.*//')
  do head -n $(($AFTER+$i)) $FILE | tail -n $(($AFTER+$BEFORE+1))
done
rm $FILE

Speichern Sie diese Datei unter grep-context.shund ersetzen Sie sie grep -C1durch ./grep-context.sh 1meinen obigen Befehl.

Eine andere Möglichkeit, die meiner Meinung nach ein für alle Mal funktioniert, besteht darin, GNU grep unter AIX zu kompilieren. (Kompilieren Sie zur Sicherheit auch GNU sed.)

Antwort3

Sie können dieses Skript verwenden:

#!/bin/sh
read START
read END
read MATCH

REND=$(grep -n "$END" lines | tail -1 | cut -d":" -f 1)
RSTART=$(grep -n "$START" lines | head -1 | cut -d":" -f 1)

sed $RSTART,$REND!d lines | grep "$MATCH"

Legen Sie es in eine Datei und fügen Sie mit diesem Befehl die Ausführungsberechtigung hinzu

chmod +x script.sh

START-Variable:Ihre Startnummern (zB 0010)

END-Variable:Ihre Endvariable (zB 0070)

MATCH-Variable:Das gesuchte Wort/Zeichen/die gesuchte Zahl in einer Zeile (zB 0012)

RSTART-Variable:Die Nummer der Startzeile in der Textdatei (z. B. 1)

REND-Variable:Die Nummer der Startzeile in der Textdatei (z. B. 32)


BEARBEITEN:

Sie können auch sehen, wie oft eine Zeile wiederholt wird, indem Sie die letzte Zeile wie folgt ändern:

sed $RSTART,$REND!d lines | grep "$MATCH" | sort | uniq -c

verwandte Informationen