슬래시와 그 뒤의 모든 내용이 제거되도록 여러 파일의 fasta 헤더를 편집하려고 합니다("이후의 모든 내용"이 10자 이하인 경우). 헤더 행은 ">"로 표시됩니다.
for i in ./*.fa;do sed -r 's/(>.*)\/.\{,10\}\n/\1\n/' "$i"; done
나도 시도했다
for i in ./*.fa;do sed -r 's/(>.*)\/.{,10}\n/\1\n/' "$i"; done
하지만 상황은 나아질 기미가 보이지 않습니다. 내 직감으로는 {,10} 수량자가 모든 것을 깨뜨린다는 것입니다. 하지만 잘 모르겠습니다. 도와주셔서 감사합니다!
예를 들어, 파일에 다음이 포함되어 있는 경우:
>header1_some_extra_data_here/1-1000
ATGCGGGTACCCCA
>code/header2_some_extra_data
AGGTCCCCGGGAAAAA
출력이 다음과 같기를 원합니다.
>header1_some_extra_data_here
ATGCGGGTACCCCA
>code/header2_some_extra_data
AGGTCCCCGGGAAAAA
답변1
sed
입력 데이터에서 개행 문자를 일치시킬 수 없기 때문에 교체가 예상대로 작동하지 않습니다 . 이는 sed
파일이 한 줄씩 읽혀지기 때문입니다 . 즉, 줄 바꿈을 구분 기호로 사용하고 표현식은 구분 줄 바꿈을 사용하지 않고 줄에 개별적으로 적용됩니다.
대신 코드를 약간 변경하세요.
for fasta in ./*.fa; do
sed 's;^\(>.*\)/.\{0,10\}$;\1;' "$fasta"
done
내가 변경한 사항은 다음과 같습니다.
- 기본값 대신 명령
;
의 구분 기호 로 사용됩니다 . 이로 인해 우리는 패턴의 문제 에서 벗어날 수 없게 됩니다 . 거의 모든 문자를 구분 기호로 사용할 수 있지만 패턴이나 대체 텍스트에 표시되지 않는 문자를 선택해야 합니다.s///
/
/
- 표준 기본 정규식 구문을 사용하세요. 패턴에서
(...)
확장 정규식 구문은\{...\}
기본 정규식 구문입니다. 이식성을 위해 기본 구문을 사용하기로 결정했습니다. 이는 또한-r
GNU에서 확장 구문을 활성화하는 옵션을 포기한다는 의미이기도 합니다sed
. - 패턴을 사용하여 선의 시작과
^
끝 부분 에 각각 고정합니다$
. - 대체 비트에 개행 문자를 삽입하려고 하지 마세요.
sed
그것을 표현하는 또 다른 짧은 방법은 다음과 같습니다.
sed '/^>/s;/.\{0,10\}$;;'
>
그러면 해당 문자로 시작하는 모든 줄 에 대체가 적용됩니다 ( /^>/
후속 명령의 "주소" 역할 s///
). 교체는 단순히 /
줄 끝까지 이어지는 비트를 삭제합니다.만약에이 비트의 길이는 10자 이하입니다.
답변2
다음은 약간 다른 접근 방식입니다.
출력을 새 파일에 저장합니다.
for file in *fa; do sed -E 's|^\s*(>.{10,}.*)/.*|\1|' "$file" > "$file.fixed"; done
해당 위치에서 파일을 편집합니다.
sed -i -E 's|^\s*(>.{10,}.*)/.*|\1|' *.fa
이 -E
옵션을 사용하면 확장 정규식을 사용할 수 있습니다. 이를 통해 ()
캡처 및 {}
반복을 이스케이프하지 않고 사용할 수 있습니다 . 명확성을 위해 구분 기호를 로 변경 |
하고 추가했습니다 ^\s*
(귀하의 지원이 지원되지 않을 수 있습니다 sed
. 그렇지 않은 경우 ^ *
때로는 앞에 공백이 있을 수 있으므로 대신 사용할 수 있습니다 >
). 왜냐하면 때때로 fasta 파일에 있기 때문입니다.
그런 다음 비결은 a >
뒤에 10개 이상의 문자를 a 까지 일치시키고 /
해당 문자를 괄호로 묶어 일치하도록 캡처한 \1
다음 전체 줄을 일치하는 부분으로 바꾸는 것입니다.
이렇게 하면 가장 긴 10자를 초과하여 마지막 문자까지 찾습니다 /
. 따라서 동일한 행이 여러 개 있으면 /
마지막 행을 제외한 모든 행이 유지됩니다. 예를 들어:
$ echo ">header1_some_extra_data_here/1-1000/foo/bar/baz" |
sed -E 's|^\s*(>.{10,}.*)/.*|\1|'
>header1_some_extra_data_here/1-1000/foo/bar
이를 방지하고 첫 번째 문자 뒤의 모든 항목을 제거하려면 /
(10자 일치하는 경우) 다음을 사용하십시오.
sed -E 's|^\s*(>.{10}[^/]*)/.*|\1|'