나는 매우 일관되게 형식이 지정되고 내가 통제할 수 있는 로그 파일을 가지고 있습니다. 일정한 길이의 파이프로 구분된 필드를 생성합니다.
내가 만들고자 하는 필터링 프로세스와 관련된 두 개의 필드가 있습니다. 이를 기본 및 보조라고 부르겠습니다.
Grep을 사용하면 먼저 주요 콘텐츠를 필터링할 수 있습니다. 이렇게 하면 관련 행의 불완전한 목록이 생성됩니다. 보조 필드에 서로 다른 두 값 중 하나를 갖는 여러 행이 이 목록에 나타납니다. 기본 필드와 일치하지 않지만 하나 또는 다른 보조 필드 값과 일치하는 기본 필드가 비어 있는 다른 행이 있습니다. 이 모든 줄은 서로 관련되어 있습니다. 최종 출력에 나타나기를 원하지만 초기 단계를 완료할 때까지는 알 수 없습니다.
일치하는 보조 필드가 있는 모든 항목에는 초기 기본 필드 또는 빈 기본 필드가 있습니다. 어떤 경우에도 보조 필드는 비어 있지 않습니다.
내 전략은 1. 로그 파일을 한 번 awk하고 기본 필드와 일치하는 모든 줄을 제거하는 것입니다(이것이 스크립트에 대한 입력이 됩니다). 이러한 각 행에 대해 두 개의 가능한 일치하는 보조 필드 값이 발견될 때까지 보조 필드가 확인됩니다. 2. 로그 파일을 다시 확인하고 기본 필드가 일치하거나 보조 필드가 첫 번째 단계에서 학습된 두 값 중 하나와 일치하는 모든 줄을 제거합니다.
1라운드에서 학습한 두 개의 보조 필드 값을 어떻게 저장한 다음 이를 사용하여 2라운드의 조건을 작성할 수 있나요?
예시를 제공해 달라는 요청을 받았기 때문에 여기에 요점을 설명하는 단순화된 데이터 버전이 있습니다. "Major"는 필드 2이고 "minor"는 필드 3입니다.
첫 번째 Pull입니다. (입력값은 05478900172입니다.)
2015-03-10 09:13:40,598|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,617|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,617|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,626|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,626|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:14:16,686|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,695|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,705|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,705|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,714|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,714|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:23,838|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,878|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,878|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S| 0
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,888|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,888|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:15:01,915|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,936|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,936|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,945|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,946|05478900172|4792761 | 17|s|D|S|----
이를 통해 보조 필드($3)에는 기본 필드에 대해 가능한 두 가지 값(4792761 또는 4792964)이 포함되어 있음을 알 수 있습니다.
우리는 스크립트에서 05478900172를 포함하는 $2의 모든 레코드와 (4792761 또는 4792964)를 포함하는 $3의 모든 레코드를 포함하는 다음 데이터 세트를 추출하기를 원합니다. 초기 스캔이 완료될 때까지 이 두 값을 모르기 때문에 이 값을 첫 번째 패스와 두 번째 패스 간에 어떻게든 공유되는 변수로 전달해야 합니다.
2015-03-10 09:13:40,598|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,608| null|4792761 |---|-|K|-|----
2015-03-10 09:13:40,608| null|4792761 |---|-|K|-|----
2015-03-10 09:13:40,617| null|4792761 |---|r|D|S|----
2015-03-10 09:13:40,617|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,617|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,626|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,626|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:14:16,686|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,695|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,696| null|4792964 |---|-|K|-|----
2015-03-10 09:14:16,696| null|4792964 |---|-|K|-|----
2015-03-10 09:14:16,704| null|4792964 |---|r|D|S|----
2015-03-10 09:14:16,705|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,705|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,714|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,714|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,760| null|4792964 |---|r|D|S|----
2015-03-10 09:14:16,760| null|4792964 |---|r|D|S|----
2015-03-10 09:14:23,817| null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,817| null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,817| null|4792964 | 42|-|D|S|7057
2015-03-10 09:14:23,817| null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,818| null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,818| null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,838|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,876| null|4792964 |---|-|K|-|----
2015-03-10 09:14:23,876| null|4792964 |---|-|K|-|----
2015-03-10 09:14:23,878|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,878|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,878| null|4792964 |---|r|D|S|----
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,879| null|4792964 |---|r|D|S|----
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S| 0
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,888|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,888|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:15:01,915|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,925| null|4792761 |---|-|K|-|----
2015-03-10 09:15:01,925| null|4792761 |---|-|K|-|----
2015-03-10 09:15:01,936| null|4792761 |---|r|D|S|----
2015-03-10 09:15:01,936|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,936|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,945|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,946|05478900172|4792761 | 17|s|D|S|----
답변1
@KM의 요청에 따라 내 답변은 다음과 같습니다.
#! /bin/sh
# this script pulls all rows from a log that are directly or
# indirectly related to a given session id. Session IDs are stored
# in $2 of each row. This field may be null. Directly related
# rows are those with $2 matching the supplied parameter. Indirectly
# related rows are those with $3 (aka xid) matching $3 in some other
# row where $2 matches the supplied parameter.
# It may be assumed that for any rows with the same $3,
# the $2 field will be identical or null.
SESS_SRCH="$1"
if [ -z $2 ]
then
LOGFILE=/path/to/default/log
else
LOGFILE=$2
fi
# pass 1:
# read the logfile once to find all unique XIDs associated
# with the supplied session ID ($SESS_SRCH)
XIDS=$(awk -F\| -v sessid="$1" '$2 ~ sessid { xids[$3]=0 }
END{
for (xid in xids) {
print xid
}
}' < ${LOGFILE}
)
XID_SRCH=""
#build a search string from these xids to form a new search string.
for XID in $XIDS
do
XID_SRCH="${XID_SRCH}|${XID}"
done
#strip off the leading "|"
XID_SRCH=${XID_SRCH:1}
# pass 2
# read the logfile again, this time seaching on $3, for any of the
# xids found in pass 1.
awk -F\| -v search="$XID_SRCH" '$3 ~ search { print }' < ${LOGFILE}
답변2
다음은 여러분이 찾고 있는 작업을 수행하는 몇 가지 코드 조각입니다. 제 생각에는 문제는 논리적인 문제입니다. 이 루프의 출력은 두 번째 테스트가 완료되었는지 여부에 관계없이 동일합니다. 왜냐하면 일치가 발생할 때마다 발생하기 때문입니다. . 두 번째로 awk를 실행할 때 설명하는 것보다 더 복잡한 테스트를 수행해야 할 것 같습니다.
이 코드 조각이 수행하는 작업은 먼저 데이터 파일에서 필드 2와 일치하는 모든 행을 추출하고, 필드 3을 추출한 다음 정렬 및 uniq를 사용하여 필드 3에 대한 중복 항목을 제거하는 것입니다. 그런 다음 각 uniq 필드 3 값에 대해 while 루프(4792761 또는 4792964)를 실행합니다. 하지만 이번에는 PATTERN에 대해 필드 2를 테스트하고 루프 값에 대해 필드 3을 테스트합니다.
PATTERN="05478900172"
awk -F\| -v matchpat="$PATTERN" '$2 ~ matchpat {print $3}' | sort | uniq | while read field
do
awk -F\| -v matchpat=$PATTERN -v secondpat="$field" '$2 ~ matchpat { if ( $3 ~ secondpat ) {print $0}}' datafile
done
이제 필드 3을 정렬 키로 사용하여 첫 번째 awk 명령의 출력을 정렬하여 단순화하고 while 루프를 제거할 수 있기 때문에 설명하는 것보다 더 복잡한 작업을 수행하고 싶어할 것 같습니다.