같은 헤더와 다른 벡터가있는 여러 파일이 있습니다. 나는 그것들을 모두 연결해야하지만 첫 번째 파일의 헤더 만 연결하기를 원하고 다른 헤더는 모두 동일하기 때문에 연결하고 싶지 않습니다.
예를 들면 다음과 같습니다. 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
위의 ” ” 와 유사한 또 다른 솔루션은 tail
and head
:
-
첫 번째 파일의 헤더를 출력에 작성하십시오.
head -2 file1.txt > all.txt
–
head -2
파일의 첫 줄 2 개를 가져옵니다. -
모든 파일의 내용을 추가하십시오.
tail -n +3 -q file*.txt >> all.txt
-3 번째부터 끝까지 인쇄 행을
-n +3
만들고 , 파일 이름 (읽기 )으로 헤더를 인쇄하지 말라고하고 파일 에
추가하며을 덮어 쓰지 않습니다 .tail
-q
man
>>
>
그리고 두 명령을 한 줄에 넣을 수 있습니다.
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
노트
:
array=( files*.txt )
{ cat ${array[@]:0:1}; grep -v "^<header" ${array[@]:1}; } > new_file.txt
그것은이다 bash는 배열 슬라이싱 기술.
답변
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 -v
sputnik이 보여 주듯이 더 간단한 접근 방식입니다.
답변
짧은 (반드시 빠른)와 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에 추가하십시오 .