교차점을 찾는 간단한 스크립트를 작성하고 싶습니다.여러 파일(모든 파일의 공통 라인), 따라서 일부 항목을 읽은 후(협회) bash 스크립트를 작성하려고 시도했지만 불행히도 실패했습니다. 내가 뭘 잘못했나요?
RES=$(comm -12 ${1} ${2})
for FILE in ${@:3}
do
RES=$(comm -12 $FILE ${RES})
done
parallel
또는를 사용하여 이를 달성하는 방법에 대한 다른 제안 사항이 있습니까 xargs
?
답변1
함수는 재귀적 방법을 허용합니다.
f() {
if (($# == 1))
then
cat $1;
return;
fi
comm -12 $1 <(f "${@:2}")
}
f file1 file2 file3 file4 file5...
답변2
역참조할 때 RES
:
comm $FILE ${RES}
content RES
replacement ${RES}
. 그러나 인수로 파일 comm
이름이 필요합니다. 예를 들어 $RES
포함이 .hello
comm
hello
대신 임시 파일을 사용하여 프로시저 내에 공통 줄을 저장할 수 있습니다.
tmp=$(mktemp --tmpdir)
tmp2=$(mktemp --tmpdir)
comm -12 ${1} ${2} >$tmp
for FILE in ${@:3}
do
comm -12 $FILE $tmp >$tmp2
rm $tmp
mv $tmp2 $tmp
done
cat $tmp
rm $tmp
답변3
아니요 parallel
, 필요 xargs
하지 않습니다 comm
. 기능을 사용해 보세요
$ intersection() { sort $@ | uniq -c | sed -n "s/^ *$# //p"; }
$ intersection file[1-3]
line2
line4
답변4
문제는 comm
두 개의 파일이 필요하고 $RES
변수라는 것입니다.
하지만 우리는 할 수 있어요속이다그리고 프로세스 대체를 사용하여 파일처럼 보이게 만듭니다.
#!/bin/bash
RES=$(comm -12 ${1} ${2})
for FILE in ${@:3}
do
RES="$(comm -12 $FILE <(printf %s "${RES}"))"
done
printf %s "$RES"
보시다시피 원본과 거의 동일하지만 구조를 사용하여 <(...)
명령을 실행하고 이를 파일 이름으로 사용하고 있습니다.
따라서 다음 세 가지 파일이 있는 경우:
a:line1
a:line2
a:line3
a:line4
b:line2
b:line4
b:line6
c:line2
c:line4
c:line8
우리는 그것들을 비교할 수 있습니다:
% ./allcomp a b c
line2
line4