내 폴더에 12,000개의 파일이 있고 더 큰 파일에 대해 csplit을 사용하고 있기 때문에 비슷한 명명 규칙이 있습니다. 파일의 첫 번째 줄을 기준으로 이러한 파일을 정렬한 다음 유사한 파일을 연결해야 합니다.
각 파일의 첫 번째 줄은 ">1", ">2", ">3" 또는 ">4"로 시작하므로 궁극적으로 모든 ">4" 파일이 하나의 응집력 있는 파일로 끝나야 합니다. 이 >4 헤더를 제거할 필요가 없습니다)
예:
파일 xx1 xx3000 및 xx449는 다음과 같습니다.
> 4 speciesX1
ATGC
나는 그것이 다음과 같이 보이도록 해야 한다
> 4 speciesX1
ATGC
> 4 speciesX3000
ATGC
> 4 speciesX449
ATGC
sed -n -e '/> 4/,/>/ p' big_file >speciesX.txt를 사용하여 원본 파일을 분할하려고 시도했지만 원하는 청크가 인쇄되지 않았으므로 누구든지 나를 도울 수 있습니까?
답변1
awk 'FNR==1 && ! /^> 4/ {nextfile}1' * > speciesX.txt
현재 파일이 첫 번째 줄로 시작하지 않으면 다음 파일로 이동합니다 > 4
. 다른 모든 행은 표준 출력으로 인쇄됩니다. stdout은 speciesX.txt
쉘에 의해 리디렉션됩니다.
참고: 1
스크립트 끝 부분에true로 평가됨, awk의 기본 작업이 수행되도록 합니다(현재 줄 인쇄). awk
awk 스크립트는 기본적으로 test-condition { action-if-true }
테스트 조건이나 작업을 생략할 수 있는 일련의 규칙이기 때문에 이는 일반적인 관용어입니다 . 테스트 조건이 없으면 항상 해당 동작이 수행되고, 동작이 없으면 print
기본값이 사용됩니다.
위의 줄을 일치 등에 맞게 수정하고 실행할 때마다 다른 파일로 리디렉션하는 것은 쉽지만 /^> 1/
모든 /^> 2/
입력 파일에 대한 출력 파일을 한 번에 만들고 스크립트를 한 번만 실행하려면 다음과 같이 할 수 있습니다. 것들:
awk 'FILENAME ~ /\.out$/ {nextfile};
FNR==1 && ! /^> [0-9]/ {nextfile};
FNR==1 {outfile=$2 ".out"};
{print > outfile}' *.txt
먼저 현재 입력 파일이 로 끝나는지 확인합니다 .out
. 그렇다면 다음 파일로 점프합니다. 모든 입력 파일이 예를 들어 끝나는 경우에는 필요하지 않지만, .txt
그것이 사실인지는 모르겠고(말하지 않았음) 해당 사례를 적절하게 처리하는 것이 더 나을 것입니다.
>
그런 다음 각 파일의 첫 번째 줄을 확인하고 허용 가능한 패턴(예: "로 시작하고 공백, 숫자가 뒤따름")과 일치하지 않으면 다음 파일로 이동합니다.
그렇지 않으면 출력 파일 이름을 구성하기 위해 첫 번째 줄의 두 번째 필드에 ".out"이 추가됩니다.
그러면 입력의 각 줄이 출력 파일 이름으로 인쇄됩니다. 파일,,, 1.out
등 으로 끝날 것입니다 . 나중에 를 사용하여 이름을 바꿀 수 있습니다.2.out
3.out
4.out
mv
awk에서의 리디렉션은 셸에서와 약간 다르게 >
작동합니다 .>>
- 쉘은 기존 파일을 삭제하고 덮어씁니다.
>
당신이 사용할 때 마다(파일에 추가를 사용해야 합니다>>
). - awk는 파일을 삭제하고 덮어씁니다.오직첫 번째파일 이름이 보입니다단일 스크립트 실행 내에서, 모든 후속 출력은 동일한 파일 이름에 추가됩니다(동일한 스크립트 실행 내에서).
>>
이렇게 하면 스크립트가 처음으로 파일 이름을 확인하더라도 삭제 및 덮어쓰기가 방지됩니다. 즉, 항상 추가됩니다.
그런데 스크립트의 마지막 줄은 {print > outfile}
테스트 조건 없이 작업을 수행하는 awk 규칙의 예입니다. 이는 각 입력 라인에 대해 수행됩니다(이전 규칙이 다음 라인이나 파일과 유사하게 작동 next
하거나 즉시 점프하지 않는 한).nextfile
답변2
이 시도:
IFS=$'\n' i=1; for header in $(egrep -m1 '> [0-9]' * -oh | sort | uniq); do grep -rl "$header" . | xargs -I{} cat {} >> file${i}; ((i++)); done
12000개의 파일이 포함된 디렉터리에서 이 명령을 실행하면 file1, file2, file3 등이라는 별도의 파일이 생성됩니다. 각 파일에는 (">1", ">2"로 시작하는 동일한 헤더가 있는 연결된 파일이 포함되어 있습니다. 모든 파일이 함께 .
설명하다:
egrep -m1 '> [0-9]' * -oh | sort | uniq - find all headers starting with "> number" ("> 1", "> 2") and remove duplicates.
IFS=$'\n' i=1; for header in $(...); do ...; done - iterate over the list of headers.
grep -rl "$header" . | xargs -I{} cat {} >> file${i}; ((i++)); - for each header concat all files started by the header to a separate file.