다음 쿼리가 도움이 되었다면 감사하겠습니다. 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와 호환되며 sed
GNU -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