두 개의 파일이 있습니다.
a.txt
1
2
3
b.txt
foo
bar
baz
qux
달리는paste a.txt b.txt
1 foo
2 bar
3 baz
qux
그러나 가장 짧은 파일의 끝에서 멈추고 싶습니다. 즉, 전체 행만 인쇄하고 싶습니다. 그렇지 않으면 파이프라인의 후속 프로그램은 qux
첫 번째 필드가 두 번째 필드인 것으로 생각할 것입니다. 방법 ). 어떻게 해야 하나요?
답변1
다른 답변과 같은 아이디어 - 모든 행을 붙여넣은 다음 전체 행을 선택하지만 다음을 사용하십시오 awk
.
paste a.txt b.txt | awk NF==2
답변2
시작 번호가 누락된 줄은 다음 명령을 사용하여 sed
삭제할 수 있습니다 .
paste a.txt b.txt | sed '/^\s/d'
결과:
1 foo
2 bar
3 bax
답변3
줄과 파일 수를 계산합니까 head
?
프로세스 대체가 포함된 <(…)
쉘이 필요합니다(bash 사용).
$ a=$(wc -l <a.txt)
$ b=$(wc -l <b.txt)
$ if [ "$a" -lt "$b" ]; then min=$a; else min=$b; fi
$ paste <( head '-'"$min" <a.txt ) <(head '-'"$min" <b.txt)
1 foo
2 bar
3 bax
답변4
이 명령을 사용할 수 있으며 대부분의 POSIX에서 작동합니다 sh
(즉, bashism 없이).
paste a.txt b.txt | head -n $( { wc -l <a.txt; wc -l b.txt; } | sort -n | head -n 1 )
paste
출력을 로 파이프하기 때문에 head -n <lines>
줄 수가 적은 파일만 통과할 수 있습니다.
다음은 주석이 달린 버전입니다.
# We let `paste` do its job normally, with output send into a pipe...
paste a.txt b.txt |
# ...to `head`, which will stop said output after `-n` lines...
head -n $(
# ...that are determined by the `wc` counted line lengths `-l` ...
{
wc -l <a.txt # ...of file a.txt...
wc -l <b.txt # ...and file b.txt ...
} |
# ... being piped to be `sort`ed numerically ascendet list...
sort -n |
# ... where the lower line count being the first line (i.e. "3)
head -n 1
)
그리고
cat >a.txt << 'EOF'
1
2
3
EOF
# and
cat >b.txt << 'EOF'
foo
bar
baz
qux
EOF
# running...
paste a.txt b.txt | head -n $( { wc -l <a.txt; wc -l b.txt; } | sort -n | head -n 1 )
...원하는 출력을 생성합니다.
1 foo
2 bar
3 bax
SIGPIPE
대부분의 설정에서는 위에서 설명한 대로 신호가 발생 해야 합니다 .man pipe(7)
해야 한다:
파이프의 읽기 끝을 참조하는 모든 파일 설명자가 닫힌 경우 write(2)는 호출 프로세스에 대해 SIGPIPE 신호가 생성되도록 합니다.
이는 많은 양의 데이터를 처리할 때 paste
많은 계산 노력이 낭비되지 않는다는 것을 의미합니다.