파일을 한 줄씩 어떻게 병합합니까?


22

고양이 파일 1

foo
ice
two

고양이 파일 2

bar
cream
hundred

원하는 출력 :

foobar
icecream
twohundred

내 시나리오에서는 파일을 쉽게 만들 수 있도록 file1과 file2에 항상 같은 양의 줄이 있습니다.

답변:


34

이 직업에 적합한 도구는 아마도 paste

paste -d '' file1 file2

자세한 내용 man paste을 참조하십시오.


다음 pr명령을 사용할 수도 있습니다 .

pr -TmJS"" file1 file2

어디에

  • -T 페이지 매김 해제
  • -mJ m의 erge 파일, J oining 전체 라인
  • -S"" 빈 문자열로 열을 분리하십시오

당신이 경우 정말 순수한 bash 쉘을 (권장하지 않음)를 사용하고 싶어,이 내가 좋을 것 것입니다 :

while IFS= read -u3 -r a && IFS= read -u4 -r b; do 
  printf '%s%s\n' "$a" "$b"
done 3<file1 4<file2

(제목이 다른 제안 된 순수 배쉬 솔루션에 대한 의견을 제시했기 때문에 이것을 포함하는 것만)


1
아주 간단한 해결책에 감사드립니다. 페이스트를 사용할 때 이식성에 대해 걱정해야합니까?
TuxForLife

1
@ user264974 paste는 GNU Coreutils에 있으므로 상당히 안전합니다.
nettux

8

를 통해 방법 :

awk '{getline x<"file2"; print $0x}' file1
  • getline x<"file2"file2 에서 전체 행을 읽고 x 변수를 보유 합니다.
  • print $0x에서 전체 라인 인쇄 파일 1을 사용하여 $0다음 x의 저장된 라인 인 파일 2 .

awk 대안을 사용하는 것이 좋습니다. 대신 이것을 사용할 수도 있습니다!
TuxForLife

4

paste갈 길입니다 . 다른 방법을 확인하려면 python해결책이 있습니다.

#!/usr/bin/env python2
import itertools
with open('/path/to/file1') as f1, open('/path/to/file2') as f2:
    lines = itertools.izip_longest(f1, f2)
    for a, b in lines:
        if a and b:
            print a.rstrip() + b.rstrip()
        else:
            if a:
                print a.rstrip()
            else:
                print b.rstrip()

줄 수가 적을 경우 :

#!/usr/bin/env python2
with open('/path/to/file1') as f1, open('/path/to/file2') as f2:
    print '\n'.join((a.rstrip() + b.rstrip() for a, b in zip(f1, f2)))

줄 수가 같지 않으면이 줄은 파일의 마지막 줄에서 끝납니다.


3

또한 순수하게 bash(빈 줄은 완전히 무시한다는 점에 유의하십시오) :

#!/bin/bash

IFS=$'\n' GLOBIGNORE='*'
f1=($(< file1))
f2=($(< file2))
i=0
while [ "${f1[${i}]}" ] && [ "${f2[${i}]}" ]
do
    echo "${f1[${i}]}${f2[${i}]}" >> out
    ((i++))
done
while [ "${f1[${i}]}" ]
do
    echo "${f1[${i}]}" >> out
    ((i++))
done
while [ "${f2[${i}]}" ]
do
    echo "${f2[${i}]}" >> out
    ((i++))
done

이것은 명백한 잘못입니다. 전혀 작동하지 않습니다. 어느 쪽의 사용은 mapfile배열로 파일을 읽거나 두 사람과 함께 while 루프를 사용하는 read각각의 자신의 FD에서 읽기, 명령.
geirha

@geirha 당신 말이 맞아요, 구문을 엉망으로 만들었습니다. 이제 괜찮습니다.
kos

좀 빠지는. 업데이트 된 코드를 사용하면 빈 줄이 무시되고 줄에 glob 문자가 포함 된 경우 줄이 일치하는 파일 이름으로 바뀔 수 있습니다. 그래서 사용하지 않습니다 array=( $(cmd) )array=( $var ). mapfile대신 사용하십시오 .
geirha

@geirha 물론 당신은 글로브 문자를 처리했지만 줄 바꿈을 무시했습니다. 왜냐하면 개행을 무시하고 그것을 해결하기 위해서는 다시 작성해야하기 때문입니다. 나는 이것을 지정하고 그 동안 누군가에게 유용 할 수 있도록이 버전을 남겨 둘 것입니다. 지금까지 포인트 주셔서 감사합니다.
kos

2

이해하기 쉬운 펄 방식 :

#!/usr/bin/perl
$filename1=$ARGV[0];
$filename2=$ARGV[1];

open(my $fh1, "<", $filename1) or die "cannot open < $filename1: $!";
open(my $fh2, "<", $filename2) or die "cannot open < $filename2: $!";

my @array1;
my @array2;

while (my $line = <$fh1>) {
  chomp $line;
  push @array1, $line;
}
while (my $line = <$fh2>) {
  chomp $line;
  push @array2, $line;
}

for my $i (0 .. $#array1) {
  print @array1[$i].@array2[$i]."\n";
}

로 시작 :

./merge file1 file2

산출:

foobar
icecream
twohundred
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.