스크립트의 동일한 입력 파일에 대해 두 개의 awk 실행 간에 공유되도록 스크립트에 변수를 저장하려면 어떻게 해야 합니까? [폐쇄]

스크립트의 동일한 입력 파일에 대해 두 개의 awk 실행 간에 공유되도록 스크립트에 변수를 저장하려면 어떻게 해야 합니까? [폐쇄]

나는 매우 일관되게 형식이 지정되고 내가 통제할 수 있는 로그 파일을 가지고 있습니다. 일정한 길이의 파이프로 구분된 필드를 생성합니다.

내가 만들고자 하는 필터링 프로세스와 관련된 두 개의 필드가 있습니다. 이를 기본 및 보조라고 부르겠습니다.

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 루프를 제거할 수 있기 때문에 설명하는 것보다 더 복잡한 작업을 수행하고 싶어할 것 같습니다.

관련 정보