구분 기호 트리플 파이프 기호 "|||"를 사용하여 두 파일을 한 줄씩 병합


14

두 언어로 같은 수의 줄을 가진 두 개의 병렬 파일이 있으며이 두 파일을 구분 기호와 한 줄씩 병합 할 계획 |||입니다. 예를 들어 두 파일은 다음과 같습니다.

파일 A :

1Mo 1,1 I love you.
1Mo 1,2 I like you.
Hi 1,3 I am hungry.
Hi 1,4 I am foolish.

파일 B :

1Mo 1,1 Ich liebe dich.
1Mo 1,2 Ich mag dich.
Hi 1,3 Ich habe Durst.
Hi 1,4 Ich bin neu.

예상되는 결과는 다음과 같습니다.

1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. ||| Hi 1,4 Ich bin neu.

나는 다음 paste과 같은 명령을 시도 했다.

paste -d "|||" fileA fileB

그러나 반환 된 출력에는 다음과 같은 파이프가 하나만 포함됩니다.

1Mo 1,1 I love you. |1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. |1Mo 1,2 Ich mag dich.

트립 파이프로 각 라인 쌍을 분리하는 방법이 |||있습니까?


8
paste -d '|||' fileA - - fileB < /dev/null
Stéphane Chazelas

5
외주이지만 번역은 정확하지 않습니다;) "Ich habe Durst"= 나는 이티 티, "Ich bin neu"= 나는 새롭다 ... 반드시 어리석은 것을 의미하지는 않습니다. ... 다만 경우에 당신은 실제로 ... 독일어 학습
dave_alcarin

@ StéphaneChazelas Thx,하지만 내 출력에는 여전히 하나의 파이프 만 포함되어 있습니다 ...
Frown

트윗 담아 가기
Frown

답변:


20

POSIX 붙여 넣기 :

:|paste -d ' ||| ' fileA - - - - fileB

paste모든 입력 파일의 해당 줄을 연결합니다. 여기에서 우리는 여섯 개 파일이 fileA, 표준에서 4 개 더미 파일을 -, 그리고 fileB.

구분 기호 목록에는 공백, 세 개의 파이프 및 그 순서의 공백이 paste원형 으로 사용됩니다 .

6 개 파일의 첫 번째 행의 fileA경우 첫 번째 더미 파일 ( no-op : operator 덕분에 아무것도 아님)과 연결되어 생성 line1-fileA<space>됩니다.

첫 번째 더미 파일은 파이프에 의해 두 번째 더미와 연결되고 line1-fileA |, 그 다음 세 번째 더미 파일과 함께 두 번째 더미 파일은 생성 line1-fileA ||하고, 네 번째 더미 파일과 함께 세 번째 더미 파일은 생성 line1-fileA |||합니다.

그리고 함께 앞으로 더미 파일 fileB생산, line1-fileA ||| line1-fileB.

이 단계는 모든 라인에 대해 반복되며 예상 결과를 제공합니다.


사용은 :|타이핑이 적고 주로 대화식 쉘에서 사용됩니다. 스크립트에서 다음을 사용해야합니다.

</dev/null paste -d ' ||| ' fileA - - - - fileB

서브 쉘이 생성되지 않도록합니다.


1
+1 :|. </dev/null
cas

4
...와 함께 표준 입력에서 4 개의 더미 파일을 스마트하게 사용하려면 +1 - - - -하지만 다음에는 설명을 위해 몇 줄을 쓸 수도 있습니다.)
Hastur

Thx,하지만 여전히 파이프 하나만으로 출력을 얻습니다.
Frown

@ hui, 모든 대시와 공백 문자를 포함하여 주어진대로 정확하게 명령을 실행 했습니까? 운영 체제가 무엇입니까?
Stéphane Chazelas

:|paste -d '|' fileA - - fileB공백 구분 기호없이 더 정확한 버전을 제공합니다.
Pål GD

7

글쎄, 이것은 sed, awk 또는 grep을 사용하지 않지만 bash에서 꽤 쉽게 할 수 있습니다. 명령은 다음과 같습니다.

(while IFS= read -r a <&3 && IFS= read -r b <&4; do echo "$a ||| $b"; done) 3<fileA 4<fileB

붙여 넣기의 문제점은 분리 문자가 단일 문자라는 것입니다. 단일 문자와 sed를 사용하여 문자를 변환 할 수도 있지만 문자가 입력 파일에 이미 표시되어 있으면 오류가 발생하기 쉽습니다.


2
줄에 백 슬래시 문자가 포함되어 있거나 대시로 시작하면 솔루션이 작동하지 않습니다. IFS=각각 전에 사용하고 싶습니다 read. 당신은 쉽게 그것을 할 수 있습니다 paste. 보기 내 대답 도하고, 이것을 사용하지 않도록해야하는 이유를 볼 수있는 while쉘 스크립트에서 루프를.
cuonglm 2011

내 파일에서 작동합니다. 많은 Thx !!!
Frown

5

awk (GNU) 버전

awk '{printf ("%s ||| ", $0); getline < "fileB"; print $0 }' fileA

getline의 명령 awk, 당신은 설정할 수 $0있는 경우, 다음 입력 레코드에서 (열의 모든 변수를) getline < "filename"당신이 다음 설정 $0지정된 파일을.

getline < "file"파일의 다음 레코드에서 $ 0을 설정합니다. NF를 설정하십시오.


왜 당신의 시도가 예상대로 작동하지 않습니까? 에서 man paste우리가 읽을 수 있습니다

-d, --delimiters=LIST
     reuse characters from LIST instead of TABs

그러나 각 열에 대해 구분 기호를 하나씩 사용합니다 .

따라서 명령
paste -d '|*|*' fileA fileB fileA fileB은 다음과 같이 줄을 제공합니다.

Hi 1,3 I am hungry.|Hi 1,3 Ich habe Durst.*Hi 1,3 I am hungry.|Hi 1,3 Ich...
Hi 1,4 I am foolish.|Hi 1,4 Ich bin neu.*Hi 1,4 I am foolish.|Hi 1,4 Ich...


sed솔루션 내가 피하기 위해 제안하는 것이 경우에도 원래의 시도에 가까운, 그것은 당신의 원래 목적에 얻어진 동작을 패치 때문에 :

 paste -d '|' fileA fileB | sed 's/|/|||/g'

각 패턴을 대체하기 때문에 피하기 위해 |새로운 하나 |||, 하지만 당신은 파이프 기호 (가정해야 |) 데이터에없는 다른, 당신은 특별한 경우를 처리하고 피하기 부작용에 더 복잡한 코드를 확인해야합니다.


Here String [ 1 ] 구문 의 변형<<<

 paste -d ' ||| ' fileA - - - - fileB  <<< ''

빈 문자열에서 데이터를 가져 오는 -d ' ||| '(space, |, |, |, space) 및 4 개의 더미 파일 ( - - - -)을 사용 하여 5 개의 구분 기호를 설정 합니다 ''.


GNU Awk 4.0.1, 페이스트 (GNU coreutils) 8.21 및 sed (GNU sed) 4.2.2에서 테스트되었습니다.


Thx, awk 명령이 작동합니다!
Frown

1
천만에요. sed(:-) 및 더 많은 주석을 피하기 위해 예제를 추가하여 답변을 업데이트했습니다 .
Hastur

4

원형 구분 기호와 더미 파일의 마법과 드라마를 피하려면 구분 기호를 붙여 넣기 전에 하나의 파일에 구분 기호를 추가하면됩니다.

paste <(sed 's/$/ |||/' filea) fileb

준다

1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. |||    Hi 1,4 Ich bin neu.

나는 이것을 단순하게 좋아한다. 나는 당신이 "첨부"가 아니라 "접두사"를 의미한다고 믿는다. 이것의 awk 버전에 대한 Checkout Hastur의 awk 답변.
와일드 카드

프로세스 대체를 파이프로 변경해야하므로이를 지원하는 쉘 수에 대한 제한이 없습니다.
cuonglm

@Wildcard 네, 접두사이지만 filea에 추가하기 위해 다시 쓸 것입니다. 나는 awk가 이것에 약간 과잉이라고 생각한다.
snth

@cuonglm 사실이지만 명확성을 위해 파이프를 피하고 싶었습니다. 파이프가 더미 파일처럼 보이게 만들 것이라고 생각했지만, 맞습니다.
snth

0

이런 식으로 파이썬에서도 할 수 있습니다.

lines1 = [ line.rstrip() for line in open("file1") ]
lines2 = [ line.rstrip() for line in open("file2") ]
for i in xrange((len(lines1))): print lines1[i] + " ||| " + lines2[i]
... 
1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. ||| Hi 1,4 Ich bin neu.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.