가장 짧은 파일에서 "붙여넣기" 명령을 중지하는 방법

가장 짧은 파일에서 "붙여넣기" 명령을 중지하는 방법

두 개의 파일이 있습니다.

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많은 계산 노력이 낭비되지 않는다는 것을 의미합니다.

관련 정보