동일한 헤더로 여러 파일을 연결 다른 헤더는 모두 동일하기

같은 헤더와 다른 벡터가있는 여러 파일이 있습니다. 나는 그것들을 모두 연결해야하지만 첫 번째 파일의 헤더 만 연결하기를 원하고 다른 헤더는 모두 동일하기 때문에 연결하고 싶지 않습니다.

예를 들면 다음과 같습니다. file1.txt

<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C

file2.txt

<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
D
E
F

나는 출력이 필요하다

<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
D
E
F

R로 스크립트를 작성할 수 있지만 쉘에서 스크립트가 필요합니까?



답변

R에서 수행하는 방법을 알고 있다면 반드시 R에서 수행해야합니다. 고전적인 유닉스 도구를 사용하면 가장 자연스럽게 awk로 수행됩니다.

awk '
    FNR==1 && NR!=1 { while (/^<header>/) getline; }
    1 {print}
' file*.txt >all.txt

awk 스크립트의 첫 번째 줄은 파일의 첫 번째 줄 ( FNR==1) 과 일치하지만 모든 파일에서 첫 번째 줄 ( )을 제외하고는 제외합니다 NR==1. 이러한 조건이 충족되면식이 while (/^<header>/) getline;실행되어 현재 awk가 regexp와 일치하는 한 awk가 다른 행을 계속 읽습니다 (현재 행 건너 뛰기) ^<header>. awk 스크립트의 두 번째 줄은 이전에 건너 뛴 줄을 제외한 모든 것을 인쇄합니다.


답변

cat+grep위의 ” ” 와 유사한 또 다른 솔루션은 tailand head:

  1. 첫 번째 파일의 헤더를 출력에 작성하십시오.

    head -2 file1.txt > all.txt

    head -2파일의 첫 줄 2 개를 가져옵니다.

  2. 모든 파일의 내용을 추가하십시오.

    tail -n +3 -q file*.txt >> all.txt

    -3 번째부터 끝까지 인쇄 행을
    -n +3만들고 , 파일 이름 (읽기 )으로 헤더를 인쇄하지 말라고하고 파일 에
    추가하며을 덮어 쓰지 않습니다 .tail-qman>>>

그리고 두 명령을 한 줄에 넣을 수 있습니다.

head -2 file1.txt > all.txt; tail -n +3 -q file*.txt >> all.txt

또는 성공 확인을 위해 그들 사이 에 ;두는 대신 &&.


답변

이것을 시도하십시오 :

$ cat file1.txt; grep -v "^<header" file2.txt
<header>INFO=<ID=DP,Number=1,Type=Integer>
<header>INFO=<ID=DP4,Number=4,Type=Integer>
A
B
C
D
E
F

노트

  • -v플래그 수단의 경기 반전하는
  • ^REGEX 수단은 문자열의 시작
  • 많은 파일이 있으면 할 수 있습니다

:

array=( files*.txt )
{ cat ${array[@]:0:1}; grep -v "^<header" ${array[@]:1}; } > new_file.txt

그것은이다 배열 슬라이싱 기술.


답변

tail(GNU, 적어도에) 명령은 초기 라인의 주어진 숫자를 건너 뛸 수 있습니다. 두 번째 줄부터 인쇄하려면, 즉 한 줄 헤더를 건너 뛰려면 다음과 같이하십시오.tail -n+2 myfile

따라서 Bash에서 첫 번째 파일의 두 줄 헤더를 유지하지만 두 번째 파일은 유지하지 않습니다.

cat file1.txt <(tail -n+3 file2.txt) > combined.txt

또는 많은 파일의 경우 :

head -n1 file1.txt > combined.txt
for fname in *.txt
do
    tail -n+3 $fname >> combined.txt
done

특정 문자열이 모든 헤더 행에 존재하지만 나머지 입력 파일에는 존재하지 않는 것으로 알려진 경우 grep -vsputnik이 보여 주듯이 더 간단한 접근 방식입니다.


답변

짧은 (반드시 빠른)와 sed:

sed -e '3,${/^<header>/d' -e '}' file*.txt > all.txt

이렇게하면 <header>...3 행부터 시작하여 모든 행이 삭제 되므로 첫 번째 헤더는 유지되고 다른 헤더는 제거됩니다. 헤더에 다른 수의 줄이있는 경우 적절하게 명령을 조정하십시오 (예 : 7대신 6 줄 헤더 사용 3).
헤더의 줄 수를 알 수 없으면 다음과 같이 시도하십시오.

sed '1{
: again
n
/^<header>/b again
}
/^<header>/d
' file*.txt > all.txt

답변

array = (* .txt); head -1 $ {array [0]}> all.txt; tail -n +2 -q $ {array [@] : 0} >> all.txt

결합 / 연결 해야하는 동일한 헤더가있는 .txt 파일이있는 폴더를 사용한다고 가정하면이 코드는 txt 파일을 모두 하나의 헤더 로 all.txt에 결합합니다 . 첫 번째 줄 (세미콜론으로 구분 된 줄)은 연결할 모든 텍스트 파일을 수집하고 두 번째 줄은 첫 번째 txt 파일에서 헤더를 all.txt 로 출력 하며 마지막 줄은 헤더없이 수집 된 모든 텍스트 파일을 헤더없이 연결합니다 ( 2 행부터 연결하여 all.txt에 추가하십시오 .