sed with numeric quantifiers-방법?
슬래시와 그 이후의 모든 것을 제거하기 위해 여러 파일의 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
답변
귀하 sed는 입력 데이터에서 개행 문자와 일치 할 수 없을 것이기 때문에 예상대로 대체 작동하지 않습니다. 그 이유는 sed줄 바꿈을 구분자로 사용하여 파일을 한 줄씩 읽고 표현식이 줄 바꿈을 구분하지 않고 줄에 개별적으로 적용되기 때문입니다.
대신 코드를 약간 변경하십시오.
for fasta in ./*.fa; do
sed 's;^\(>.*\)/.\{0,10\}$;\1;' "$fasta"
done
내가 한 몇 가지 변경 사항은 다음과 같습니다.
- 기본값 대신 명령
;의 구분 기호로 사용하십시오 . 이것은 우리가 패턴에서 탈출하지 못하게 합니다. 거의 모든 문자를 구분자로 사용할 수 있지만 패턴이나 대체 텍스트에없는 문자를 선택해야합니다.s///// - 표준 기본 정규식 구문 만 사용하십시오. 패턴에서
(...)확장 정규식 구문이며\{...\}기본 정규식 구문입니다. 이식성을 위해 기본 구문을 사용하기로 결정했습니다. 이것은 또한-rGNU에서 확장 구문을 활성화하는 옵션을 삭제하는 것을 의미 합니다sed. ^및$각각을 사용 하여 패턴을 선의 시작과 끝에 고정합니다 .- 대체 비트에 개행을 삽입하지 마십시오.
대안적이고 짧은 sed표현은 다음과 같습니다.
sed '/^>/s;/.\{0,10\}$;;'
이는 >문자로 시작하는 모든 행에 대체를 적용합니다 ( /^>/후속 s///명령 의 "주소"역할을 함 ). 대체는 해당 비트 길이가 10 자 이하인 경우/ 줄 끝까지 및 그 뒤에있는 비트 를 삭제합니다 .
다음은 약간 다른 방법입니다.
출력을 새 파일에 저장합니다.
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 개 이상의 문자 를 일치 /시키고 괄호로 이러한 문자를 캡처 \1하여 일치하는 부분만으로 전체 줄을 대체하는 것입니다.
이것은 마지막 /. 따라서 /같은 줄에 여러 줄 이 있으면 마지막 줄을 제외하고 모두 유지됩니다. 예를 들면 :
$ 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|'