awk
한 변수의 특정 열에 있는 각 행의 숫자를 다른 변수의 두 특정 열에 있는 모든 행과 비교하여 확인 하고 매개 변수와 일치하는 첫 번째 변수의 행을 유지하는 데 사용해야 합니다 .
지금까지 나는 강력한 명령을 통해 awk
이 작업을 수행하려고 시도했지만 실패했습니다. 분명히 외부 루프에서 이 작업을 수행할 수 있지만 확인할 행이 수백 또는 수천 개 있으므로 매우 느릴 것입니다. 이 문제에 대해 도움을 주시면 감사하겠습니다. 저는 항상 awk 사용을 개선하기 위해 노력하고 있습니다. 따라서 해결책이 있다면 제가 배우고 개선할 수 있도록 설명이 있으면 좋을 것입니다.
예는 다음과 같습니다.
${ListToCheckFrom}
임의의 행 > 열 2 및 < 열 3의 숫자인 경우 열 2의 행만 인쇄한다고 가정합니다.${ListToCheckAgainst}
입력 예:
ListToCheckFrom="C,2 C,22 C,12 hr,15" ListToCheckAgainst="C1,25,50 hr1,22,30 r,12,18 C,15,44"
예상 출력:
C,22 hr,15
답변1
질문에 로 태그를 지정했으므로 bash
프로세스 대체를 활용하여 입력 파일과 같은 셸 변수를 읽을 수 있습니다. 다음 스크립트 조각은 다음을 수행해야 합니다.
#!/bin/bash
ListToCheckFrom="C,2
C,22
C,12
hr,15"
ListToCheckAgainst="C1,25,50
hr1,22,30
r,12,18
C,15,44"
awk -F',' 'list=="constr"{n++; low[n]=$2;high[n]=$3;next}
{for (i=1;i<=n;i++) {if ($2>low[i]&&$2<high[i]) {print;next};}}' \
list=constr <(echo "$ListToCheckAgainst") \
list=chk <(echo "$ListToCheckFrom")
이는 echo
첫 번째 입력 파일의 내용과 두 번째 입력 파일의 내용을 지정합니다. 현재 처리 중인 "파일"을 내부적으로 구별할 수 있도록 각 파일이 "열려" 있거나 그 전에 변수를 설정합니다.$ListToCheckAgainst
echo
$ListToCheckFrom
awk
list
constr
chk
awk
- 에서 "제약조건"을 처리할 때
$ListToCheckAgainst
단순히 열 2와 3에 지정된 "하한"과 "상한"을 각각 배열low
및 에 저장합니다high
. 그렇지 않으면 즉시 다음 입력 라인으로 처리를 건너뜁니다. - 확인할 목록을 처리할 때
$ListToCheckFrom
이전에 등록된 모든 범위를 검색하고 열 2가 해당 범위 중 하나에 속하는 것을 발견하면 이를 인쇄합니다(그리고 즉시 다음 입력 라인으로 처리를 건너뜁니다).
데이터가 쉘 변수가 아닌 "물리적" 파일에 저장되어 있는 경우 프로세스 대체 대신 파일 이름을 명령줄 인수로 사용할 수 있습니다.
답변2
$ cat tst.sh
#!/usr/bin/env bash
ListToCheckFrom='C,2
C,22
C,12
hr,15'
ListToCheckAgainst='C1,25,50
hr1,22,30
r,12,18
C,15,44'
awk '
BEGIN { FS="," }
NR==FNR {
begs2ends[$2] = $3
next
}
{
for ( beg in begs2ends ) {
beg += 0
end = begs2ends[beg]+0
if ( (beg < $2) && ($2 < end) ) {
print
next
}
}
}
' <(printf '%s\n' "$ListToCheckAgainst") <(printf '%s\n' "$ListToCheckFrom")
$ ./tst.sh
C,22
hr,15