목록이 있어요
2
2
2
3
2
2
2
4
2
2
2
위와 아래의 3단계 값보다 최소 2배 더 큰 값을 동일한 열에 인쇄하고 싶습니다.
출력은
4
어떻게 하나요? 저도 비슷한 질문을 했어요여기, 더 잘 설명하기 위해 여기에 글을 쓰고 있습니다. 감사합니다.
20171006 업데이트: 실제 입력 파일을 지나치게 단순화해서 죄송합니다. 실제로는 목록이 아닌 테이블입니다. 여러 열(열 2, 3, 4 등) 중에서 선택하고 열 1을 인쇄해야 합니다. 해당 열에 대해 이와 같은 스크립트의 정보를 어떻게 병합합니까?
A 2 2 2
B 2 2 2
C 2 2 2
D 3 3 3
E 2 2 2
F 2 2 2
G 2 2 2
H 4 4 4
I 2 2 2
J 2 2 2
K 2 2 2
그리고 얻다
H
답변1
에서 이 작업을 수행할 수 있습니다 awk
. 세 번째 행과 마지막 행을 여섯 번째 행과 현재 행을 비교하려면 처음 6개 행을 저장해야 합니다. 이에 대한 일반적인 트릭은 보유하려는 행 수로 인덱스가 지정된 NR%6
배열 인 링 버퍼를 사용하는 것입니다 6
.
awk '
NR > 6 {
x = saved[NR%6]; y = saved[(NR - 3) % 6]; z = $0
if (y >= 2*x && y >= 2*z) print y
}
{saved[NR % 6] = $0}' < file
편집하려면: 비교할 키와 값을 저장하세요.
awk -v key=1 -v value=2 '
NR > 6 {
x = saved_value[NR%6]; y = saved_value[(NR - 3) % 6]; z = $value
if (y >= 2*x && y >= 2*z) print saved_key[(NR - 3) % 6]
}
{saved_key[NR % 6] = $key; saved_value[NR % 6] = $value}' < file
어디에 key
인쇄할 열의 인덱스와 value
비교할 값이 포함된 열이 있습니다.
또는 2, 3, 4열(예: 평균)을 기반으로 원하는 측정항목을 선택하세요.
awk '
{metric = ($2 + $3 + $4) / 3}
NR > 6 {
x = saved_metric[NR%6]; y = saved_metric[(NR - 3) % 6]; z = $metric
if (y >= 2*x && y >= 2*z) print saved_key[(NR - 3) % 6]
}
{saved_key[NR % 6] = $key; saved_metric[NR % 6] = $metric}' < file
답변2
메모리의 전체 파일을 읽지 않고:
paste <(tail -n+4 file.txt | head -n-3) <(head -n-6 file.txt) <(tail -n+7 file.txt) |
awk '$1 >= 2*$2 && $1 >= 2*$3 {print $1}'
<(...)
이를 위해서는 구성(AT&T ksh
또는 bash
) 을 처리할 수 있는 셸 zsh
과 head
음수 오프셋을 지원하는 구현이 필요합니다.
설명하다:위의 명령은 paste
현재 값, 3단계 위의 값, 3단계 아래의 값을 같은 줄에 넣고 awk
2배 더 큰 조건을 확인합니다.
답변3
앗해결책:
awk 'function mean(sum){
m=sum/3; return (int(m) == m)? m: int(m)+1
}
{ a[NR]=$0 }
END{
for(i=4;i<=NR-3;i++)
if (a[i]>=mean(a[i-3]+a[i-2]+a[i-1])*2 &&
a[i]>=mean(a[i+3]+a[i+2]+a[i+1])*2)
print a[i]
}' file
a[NR]=$0
- 모든 값을a
레코드 번호로 색인된 배열 로 수집NR
산출:
4
답변4
따라서 이를 수행하려면 3 + 1 + 3 입력 행의 슬라이딩 윈도우를 유지해야 합니다.
awk -vn=3 -va=2 'BEGIN { N=2*n+1 } { t=(NR-n)%N; m=NR%N; b=(NR+n)%N; w[b]=$0 } NR >= N && w[m] >= a*w[t] && w[m] >= a*w[b] { print w[m] }' file
n
이렇게 하면 조건을 만족하는 모든 값이 인쇄되며, 명령줄에서 변수를 조정(변경)하여 거리를 쉽게 수정할 수 있고, -vn=3
가중치를 변경(변경)하여 거리를 쉽게 수정할 수 있다는 추가 이점이 있습니다.a
-va=2
이 코드는 마지막 N 값을 순환 버퍼에 저장합니다. 여기서 N은 2*n + 1 입니다 w
. 중간 값이 버퍼의 첫 번째 값 ( "top"의 경우)의 배수와 버퍼의 마지막 값 ( "bottom"의 경우)의 배수 w[m]
보다 크면 이를 인쇄합니다.a
w[t]
t
a
w[b]
b
공개된 스크립트 awk
:
BEGIN { N = 2*n + 1 }
{
t = (NR - n)%N
m = NR%N
b = (NR + n)%N
w[b] = $0
}
NR >= N && w[m] >= a*w[t] && w[m] >= a*w[b] { print w[m] }