sed 명령 설명

sed 명령 설명

나는 다음과 같은 흥미로운 명령을 발견했습니다.

grep -v '^>' test.fasta | tr -d '\n' | sed -e 's/\(.\)/\1\n/g' | sort | uniq -c | sort -rn

나는 그것이 무엇을 의미하는지 어느 정도 이해하고 있습니다(텍스트 파일의 문자 수를 셉니다). 그러나 내 질문은 이것에 관한 것입니다:

sed -e 's/\(.\)/\1\n/g'

3개의 대체 명령으로 구성되어 있는 것으로 알고 있습니다. 하나는 개행 \n문자( )를 제외한 모든 문자와 일치하는 새 행( )을 대체하는 것입니다 \(.\). 그러나 /\1\?

답변1

명령

sed -e 's/\(.\)/\1\n/g'

sed모든 문자를 자체적으로 바꾸고 그 뒤에 줄 바꿈 문자가 오는 단일 GNU 대체 명령입니다 . 그 효과는 입력을 단일 문자의 단일 열로 접는 것입니다.

$ echo hello | sed -e 's/\(.\)/\1\n/g'
h
e
l
l
o

\(.\)단일 문자를 캡처하는 "캡처 그룹"입니다 . 이는 \1첫 번째 캡처 그룹에 대한 "역참조"입니다. \1대체 텍스트에 을 사용하면 첫 번째 괄호에 포함된 내용이 모두 삽입됩니다.

다음과 같이 많은 백슬래시 없이 작성할 수도 있습니다.

sed 's/./&\n/g'

여기서는 &단순히 "표현식과 일치하는 항목"을 의미합니다.

sed명령에는 sed표준으로 GNU가 필요하며 이와 같은 sed개행 문자를 삽입할 수 없습니다 \n.

표준 도구를 사용하여 보다 효율적으로 수행하려면 다음을 사용하십시오.

fold -w 1

대신에. 입력의 각 문자에 대해 정규식 일치가 필요하지 않으므로 이는 더 효율적입니다.

을 사용하면 fold파이프라인을 작성할 수 있습니다.

grep -v '^>' file | tr -d '\n' | fold -w 1 | sort | uniq -c | sort -rn

awk또는 해당 파이프라인의 몇 가지 단계를 제거하는 데 사용하는 방법은 다음과 같습니다 .

awk '!/^>/ { for (i = 1; i <= length; ++i) count[substr($0,i,1)]++ }
    END { for (ch in count) print count[ch], ch }' file |
sort -rn

코드 awk는 각 문자가 표시된 횟수를 계산합니다. count입력 스트림의 각 문자에 해당하는 배열의 값을 증가시켜 이를 수행합니다 . 입력이 끝나면 카운트된 개수와 문자 요약이 출력됩니다.

답변2

이것이 더 명확해지기를 바랍니다.

"3개의 대체 명령으로 구성되어 있는 것으로 알고 있습니다."

이는 하나의 대체 명령(명령을 참조하는 경우 sed)일 뿐입니다. s/<pattern to search>/<replacement>/이는 다음을 실행합니다.

  • 모든 줄에 대해 을 검색하여 <pattern>로 대체합니다 <replacement>.
  • 깃발 g의 의미g지역적으로는 기본적으로 의 sed첫 번째 항목만 대체하기 때문입니다 <pattern>.

"하지만 난 길을 잃었어 /\1\"

\(<pattern>\)이스케이프된 괄호로 패턴을 둘러싸 거나 -E옵션 으로 괄호만 사용하여 패턴을 캡처할 수 있습니다 (<pattern>).

섹션 에서 <replacement>이 캡처된 패턴은 백슬래시와 숫자로 참조됩니다 \<number>. 여러 개가 있을 수 있으므로 숫자는 캡처 위치를 나타냅니다.

sed -E '/(<first capture>)(<second capture>)/\1\2/'

따라서 명령은 다음을 sed -e 's/\(.\)/\1\n/g'의미합니다.

  • 모든 문자를 캡처 \(.\)하고 해당 문자와 ​​새 줄로 바꿉니다 \1\n.
  • 를 사용하면 g전역적으로 수행하고 첫 번째 발생에서 멈추지 마십시오.

예를 들어:

$ echo foo | sed -E 's/(.)/\1\n/g'
f
o
o


여러 명령을 -e연결하지 않는 한 여기에서는 옵션이 필요하지 않습니다 .sedsed -e '...' -e '...'


자세한 내용은 다음에서 확인할 수 있습니다.역참조 및 하위 표현식.

답변3

Raku(이전의 Perl_6) 사용

raku -e 'for lines.grep({ !/ ^ \> / }).join { .say for .comb.Bag.sort(*.values).reverse};'

샘플 입력:

>sp|P01308|INS_HUMAN Insulin OS=Homo sapiens OX=9606 GN=INS PE=1 SV=1
MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKTRREAED
LQVGQVELGGGPGAGSLQPLALEGSLQKRGIVEQCCTSICSLYQLENYCN

샘플 출력:

L => 20
G => 12
A => 10
E => 8
Q => 7
P => 6
C => 6
V => 6
R => 5
S => 5
Y => 4
F => 3
T => 3
N => 3
M => 2
D => 2
K => 2
I => 2
W => 2
H => 2

귀하가 제공하는 코드는 다양한 언어( 뿐만 아니라 sed)로 작성될 수 있으며, 그 중 어떤 언어라도 귀하의 마음에 쏙 들 것입니다. 예를 들어, 위의 코드는 Perl 계열 언어의 구성원인 Raku로 다시 작성되었습니다.

대부분의 Raku 코드는 상당히 자명해야 합니다. 행 시작 ' 보다 큰' 각도가 없으면 lines읽어들여 -ped하고 -ed합니다. 결합된 줄은 -ed(개별 문자로 나눔), -ged(존재하는 각 문자가 a가 되고 발생 횟수가 로 계산/기록됨 ), -ed로 발생 횟수가 가장 높은 항목을 먼저 배치한 다음 로 인쇄합니다 .grep!^>joincombBagkeyvaluessortreversesay

https://raku.org

관련 정보