파일 1:
91 23 56 44 87 77
99 34 56 22 22 95
41 88 26 79 60 27
95 55 66 69 92 25
파일 2:
pass fail pass pass pass fail
pass fail pass fail fail pass
pass pass fail pass pass fail
pass pass fail pass pass fail
각 행의 총 실패 토큰을 합산하려고 하므로 이것이 예상되는 출력입니다.
산출:
100
78
53
91
실패 토큰의 합계를 얻기 위해 file2의 "fail"이라는 단어를 기반으로 file1을 필터링하는 방법을 묻고 싶습니다.
답변1
나는 그러한 작업을 위해 GNU Octave와 같은 매트릭스 언어를 사용할 것입니다.
통과/실패 파일을 숫자 값으로 변환한다고 가정합니다. 예를 들면 다음과 같습니다.
sed 's/pass/1/g; s/fail/0/g' passfail > passfail.nums
이제 다음을 수행할 수 있습니다.
marks = dlmread('marks');
passfail = dlmread('passfail.nums');
for i = 1:size(marks)(1)
sum(marks(i,:)(passfail(i,:) == 0))
end
산출:
ans = 100
ans = 78
ans = 53
ans = 91
답변2
저는 를 사용하는 것이 이식성에 좋다고 생각하지만 awk
, 이 작업을 위해서는 다른 언어가 쓰고 읽는 것이 더 쉬운 것 같습니다. GNU Octave가 언급되었지만 대부분의 시스템에는 사전 설치되어 있지 않습니다. 반면, 대부분의 시스템에는 사전 설치된 Python 버전이 함께 제공됩니다. Python 버전은 다음과 같습니다.
for marks, decisions in zip(open('file1').readlines(), open('file2').readlines()):
row_score = 0
for mark, decision in zip(marks.split(), decisions.split()):
if decision == 'fail':
row_score += int(mark)
print(row_score)
예상한 출력을 반환합니다.
답변3
이것이 내 awk
접근 방식입니다.
awk 'NR==FNR{for(i=1;i<=NF;i++) a[NR"-"i]=$i; next} \
{for(j=1;j<=NF;j++) if($j=="fail") b[FNR]+=a[FNR"-"j]} \
END{for(k in b) print b[k]}' file1 file2
awk는 2D 배열을 지원하지 않으므로 동일한 배열 인덱스에 두 숫자(행과 필드)를 결합하여 2D 배열을 결합합니다. 출력은 다음과 같습니다
100
78
53
91
답변4
awk '
BEGIN{ pf=ARGV[2]; ARGV[2]="" }
{ getline l <pf; split(l, a); n=0;
for(i=1;i<=NF;i++) if(a[i]=="fail") n+=$i;
print n }
' file1 file2
100
78
53
91
@Maxim의 Python 버전과 비슷하지만 다른 모든 답변과 달리 이는 파일을 메모리에 완전히 로드하는 대신 두 파일을 한 줄씩 병렬로 처리합니다.