저는 제가 편집해 온 phylip 파일로 구성된 데이터세트로 작업하고 있습니다. Phylip 형식은 샘플 번호와 시퀀스 길이를 헤더로 포함하고 각 샘플과 해당 시퀀스가 뒤따르는 생물정보학 형식입니다. 예를 들어:
5 10
sample_1 gaatatccga
sample_2 gaatatccga
sample_3 gaatatcgca
sample_4 caatatccga
sample_5 gaataagcga
내 문제는 이러한 데이터 세트를 정리할 때 헤더의 샘플 수가 더 이상 정확하지 않다는 것입니다(예: 위의 예에서는 5라고 표시될 수 있지만 샘플을 3개로만 정리했습니다). 내가 해야 할 일은 샘플 수를 새롭고 정확한 샘플 수로 바꾸는 것입니다. 그러나 시퀀스 길이 번호(예: 10)를 잃지 않고 이를 수행하는 방법을 모르겠습니다.
550개의 파일이 있으므로 이 작업을 수동으로 간단히 수행할 수 없습니다. wc에 대해 for 루프를 수행할 수 있지만 다시 한 번 시퀀스 길이 정보를 유지하고 이를 새롭고 정확한 wc와 결합해야 합니다.
답변1
귀하의 요구 사항을 올바르게 이해했다면 다음 awk
명령을 사용할 수 있습니다.
awk -v samples="$(($(grep -c . input)-1))" 'NR == 1 { $1=samples }1' input
samples
파일의 줄 수에서 1을 뺀 값으로 설정합니다 input
(헤더 줄은 계산하지 않기 때문입니다).
awk
그런 다음 첫 번째 행의 첫 번째 열을 새 샘플 번호로 변경하고 모든 것을 인쇄합니다.
$ cat input
5 10
sample_1 gaatatccga
sample_2 gaatatccga
sample_3 gaatatccga
$ awk -v samples="$(($(grep -c . input)-1))" 'NR == 1 { $1=samples }1' input
3 10
sample_1 gaatatccga
sample_2 gaatatccga
sample_3 gaatatccga
GNU awk를 사용하면 해당 플래그를 사용하여 적절한 파일을 수정할 수 있지만 -i
올바른 변경이 이루어졌는지 확인하기 위해 두 번째 수정된 파일 세트를 만드는 것을 선호합니다.
그것은 다음과 같습니다:
for file in *.phy; do
awk -v samples="$(($(grep -c . "$file")-1))" 'NR == 1 { $1=samples }1' "$file" > "${file}.new"
done
답변2
또 다른 옵션은 다음을 사용하는 것입니다 ed
(물론!):
for f in input*
do
printf '1s/[[:digit:]][[:digit:]]*/%d\nw\nq' $(( $(wc -l < "$f") - 1 )) | ed -s "$f"
done
이는 파일(예: input
-something이라는 이름)을 반복하고 간단한 ed 스크립트를 다음으로 보냅니다 ed
.
- 온라인 , 줄 시작 부분에 있는 하나 이상의 숫자를
1
검색하고 대체()합니다. 대체 숫자는 입력 줄 길이에서 1을 뺀 값으로 계산됩니다.s//
- 그 후
w
파일을 작성하고 - 그런 다음
q
종료하세요.
답변3
Vim에서 다음을 실행하세요:
:execute '1s/^[0-9]\+/' . (line('$')-1) . '/'
(도 감사하다이 답변나에게 올바른 방향을 알려주었습니다. )
:bufdo
쉘 루프를 사용하거나 쉘 루프만 사용하는 등 루프에서 이 작업을 수행할 수도 있습니다 for
.