Bash 스크립트는 파일의 레코드를 반복하고 조건에 따라 값을 추출합니다.

Bash 스크립트는 파일의 레코드를 반복하고 조건에 따라 값을 추출합니다.

다음 쿼리가 도움이 되었다면 감사하겠습니다. Bash 스크립트가 필요합니다. 저는 이 스크립팅 기술을 처음 접했습니다.

어딘가에 다음 파일이 있습니다. 파일 이름이 MemberFile.txt라고 가정해 보겠습니다.

#
[ID          ]  #1
[ADDRE1      ]  Address Line #1
[ADDRE2      ]  Mumbai City
[ADDRE3      ]  India
#
[ID          ]  #2
[ADDRE1      ]  House No 2
[ADDRE3      ]  Green Society
[ADDRE4      ]  Kolkatta
#
[ID          ]  #3
[ADDRE1      ]  Plot Num 77
[ADDRE2      ]  House No # [567]
[ADDRE3      ]  greener Apt
#

파일에는 이러한 레코드가 수백만 개 있을 수 있습니다. 각 레코드를 빠르게 반복하여 가져오고 저장하고 싶습니다 [ADDRE3 ]. 또한 레코드에 "society" 또는 "Num"이라는 단어가 포함되어 있는지 확인하세요(대소문자 구분 안 함). 그렇다면 [ID ]해당 레코드의 태그 값을 가져옵니다.

예상되는 출력은 #2와 #3입니다.

아래 1은 레코드를 나타냅니다.

[ID          ]  #1
[ADDRE1      ]  Address Line #1
[ADDRE2      ]  Mumbai City
[ADDRE3      ]  India

답변1

해결책:

awk -v IGNORECASE=1 '/\[ID /{ r=$3; c=3; next }c-- && $0~/society/{ print r }' MemberFile.txt

산출:

#2
#3

  • IGNORECASE=1- 대소문자를 구분하지 않는 비교 모드 설정

  • /\[ID /{ r=$3; c=3; next }- ID레코드 번호 캡처 #<number>(세 번째 필드로)

  • c-- && $0~/society/- 다음 3개의 레코드에 society단어가 포함되어 있는지 확인하세요.

답변2

이렇게 하면 트릭을 수행할 수 있습니다.

grep -iE '(^\[ADDRE3.*society|^\[ADDRE3.*no|^\[ADDRE3.*blabla)' -B 3 MemberFile.txt | grep "ID" | grep -o "#[0-9]*"

정확히 무슨 일이 일어났는지 적어보세요:

-i따라서 정규 표현식을 사용하여 이름이나 원하는 항목에 도달할 때까지 "[ADDRE3"으로 시작하는 각 줄 뒤에 대소문자를 구분하지 않는 콘텐츠를 필터링합니다.-E^\[ADDRE3.*society|

적중하면 해당 행 + -B 3그 위의 3개 행을 표시합니다.

그런 다음 모든 행의 ID를 필터링한 다음 표시된 #Number 다음에 해당 ID를 필터링합니다.-o

주소 검색:

grep -iE '(^\[ADDRE.*society|^\[ADDRE.*no|^\[ADDRE.*blabla)' -B 3 MemberFile.txt | grep "ID" | grep -o "#[0-9]*"

답변3

perl -lne '
   next unless /^#$/ && !$flag ... /^#$/ && $flag;
   $flag++,next if /^#$/ && !$flag;
   /^\[ID\h/ and $id = s/.*\h#/#/r,next;
   push @A, $_;
   if ( (/^#$/ && $flag) ) {
      print $id if join($/, splice(@A,0,@A)) =~ /(?:^|\h)(?i:society|num)(?:\h|$)/m;
      $flag = 0; undef $id; redo;
   }
' MemberFile.txt

피복재

각 레코드는 #(플래그가 OFF)으로 시작하고 #(플래그가 ON)으로 끝납니다. 새로운 기록이 발견되면 가장 먼저 취하는 조치는 플래그를 여는 것입니다. (방에 들어갈 때 불을 켜는 것과 같습니다).

레코드에서 ID 행이 발견되면 해당 값이 저장됩니다. 레코드의 다른 모든 행의 경우 각 행을 배열에 저장합니다 @A.

레코드의 마지막 줄(/#/, 플래그 ON)에 도달하면 줄 바꿈을 사용할 때 배열 요소에 "society" 또는 "num"이라는 단어가 포함된 것으로 알려진 경우 ID를 인쇄합니다. splice배열이 지워졌습니다 .

우리는 플래그를 끄고(방을 나갈 때 해야 하는 것처럼), 같은 라인이기 때문에 다음 레코드의 시작 부분을 니블링하는 redo대신에 수행합니다 .next

거의 동일한 방법을 사용 sed하지만 배열이 없기 때문에 예약된 공간을 저장 용도로 활용합니다. 이 코드는 POSIX와 호환되며 sedGNU -isms를 사용하여 상당히 압축될 수 있습니다.

sed -e '
   /^\[ID[[:blank:]]/,/^#$/!d
   H;/^\[ID[[:blank:]]/h;/^#$/!d
   g;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
   /[[:blank:]]num$/ba
   /[[:blank:]]society$/ba
   /[[:blank:]]num\n/ba
   /[[:blank:]]society\n/ba
   /[[:blank:]]num[[:blank:]]/ba
   /[[:blank:]]society[[:blank:]]/ba
   d;:a
   s/\n.*//
   s/^\[id[[:blank:]].*#/#/
' MemberFile.txt

결과

#2
#3

관련 정보