sed while 루프 오류

sed while 루프 오류

구문 분석할 파일이 있습니다.

mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p    0610007P14Rik
mmu-miR-326-3p/330-5p   0610007P14Rik
mmu-miR-326-3p/330-5p   Lmir
mmu-miR-15/16/195/424/497   0610007P14Rik
mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p/6838-5p    0610007P14Rik
mmu-miR-15/16/195/424-5p/497    Alinf
mmu-miR-326/330-5p  0610007P14Rik
mmu-miR-326/330 0610007P14Rik
mmu-miR-1/206/613   Crgi
mmu-miR-1-3p/206    0610007P14Rik

원하는 출력:

첫 번째 행의 경우

mmu-miR-15-5p   0610007P14Rik
mmu-miR16-5p    0610007P14Rik
mmu-miR195-5p   0610007P14Rik
mmu-miR424-5p   0610007P14Rik
mmu-miR497-5p   0610007P14Rik

등...

두 번째 열과 새 행을 교체 /하고 생성 하면 됩니다 .mmu-miR

Bash에서 다음 코드 줄을 사용해 보았습니다.

sed 's/\//\nmmu-miR/g' test.txt

mmu-miR-15-5p
mmu-miR16-5p
mmu-miR195-5p
mmu-miR424-5p
mmu-miR497-5p   0610007P14Rik
mmu-miR-326-3p
mmu-miR330-5p   0610007P14Rik
mmu-miR-326-3p
mmu-miR330-5p   Lmir

while루프와 다음 sed 명령을 사용해 보았습니다 .

while read line; do 
    lineCols=( $line ); 
    v1=($(echo "${lineCols[0]}"));
    v2=($(echo "${lineCols[1]}"));
    sed 's/\//\n/g' ${v1};
done <test.txt

하지만 오류가 발생했습니다.

sed: can't read mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p: No such file or directory
sed: can't read mmu-miR-326-3p/330-5p: No such file or directory
sed: can't read mmu-miR-326-3p/330-5p: No such file or directory
sed: can't read mmu-miR-15/16/195/424/497: No such file or directory
sed: can't read mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p/6838-5p: No such file or directory

내가 뭘 잘못했나요?

답변1

이 목표를 달성하는 방법awk

더 나은 가독성/사용 편의성을 위해 다음을 포함하는 awk스크립트( )를 생성하십시오.myScript.awk

{ 
  n=split($1, a, "/")
  split(a[1], b, "-")

  for (i=1; i<n+1; i++) {
    if (i == 1) {
      printf a[i]"\t"$2"\n"
    }
    else {
      printf b[1]"-"b[2]"-"a[i]"\t"$2"\n"
    }    
  }
}

작동 방식:

n=split($1, a, "/")

이 줄은 첫 번째 줄을 취합니다.대지(예: "mmu-miR-15-5p/16-5p/195-5p/424-5p/497-5p"첫 번째 줄) 구분 기호 "/"로 분할하여 배열에 저장 a하고 분할 요소 수를 에 저장합니다 n. 첫 번째 줄의 경우:

a[1] = "mmu-miR-15-5p"
a[2] = "16-5p"
a[3] = "195-5p"
a[4] = "424-5p"
a[5] = "497-5p"
n = 5

명령 은 awk각 줄에서 실행되므로 다음 줄의 결과는 달라집니다.

split(a[1], b, "-")

마찬가지로 이 줄은 첫 번째 요소를 가져와 a구분 기호 "-"로 구분합니다. 이는 다음을 생성합니다.

b[1] = "mmu"
b[2] = "miR"
b[3] = "15"
b[4] = "5p"

a이러한 배열이 있으면 출력 행 수(입력 행에서 "/"로 구분된 요소 수)를 반복하고 배열 비트 와 ! 를 사용하여 각 행을 구성하기만 하면 됩니다 b. 첫 번째 줄에는 a[1]"mmu-miR-"이 이미 포함되어 있으므로 예외를 만들어야 하므로 if이 경우를 구별하세요!

그것을 실행하는 방법

awk -f myScript.awk input.txt

테스트한 결과 질문에서 요청한 내용이 출력되었습니다.

노트 귀하의 질문에 대한 내 의견에서 언급했듯이 단일 awk호출을 사용하는 것이 파일의 각 줄을 반복하는 것보다 더 효율적이고 "셸 친화적"입니다.

편집자 주 귀하의 의견을 바탕으로 스크립트를 수정했습니다. 이제 괜찮을 것 같아요!

답변2

나는 당신이 다음과 같은 것을 찾고 있다고 생각합니다.

cat inputFile.txt | while read line
    do
        eval `echo "$line" | sed 's|^\([^/]*\)/\([^ ]*\) \(.*\)|name="\1" ports=\2 tag="\3"|'`
        echo "$name $tag"
        realname=`echo "$name" | sed 's|-[0-9].*||'`
        for port in $(echo $ports | sed 's|/| |g')
        do
            echo "$realname-$port $tag"
            #or echo "$realname$port $tag", but I suspect a typo in your initial post
        done
    done

답변3

입력이 헤더 없는 TSV 파일(즉, 헤더 줄 없이 탭으로 구분된 파일)이라고 가정하면 다음을 사용하여 읽을 수 있습니다.밀러( mlr) 및 "중첩되지 않은" 각 레코드는 /첫 번째 필드에 -로 구분된 문자열로 구성됩니다. 그런 다음 해당 문자열 mmu-miR-을 아직 포함하지 않은 첫 번째 필드의 모든 값에 해당 문자열을 추가할 수 있습니다 .

$ mlr --tsv -N nest --evar '/' -f 1 then put -S '$1 !=~ "^mmu-miR-" { $1 = "mmu-miR-" . $1 }' file
mmu-miR-15-5p   0610007P14Rik
mmu-miR-16-5p   0610007P14Rik
mmu-miR-195-5p  0610007P14Rik
mmu-miR-424-5p  0610007P14Rik
mmu-miR-497-5p  0610007P14Rik
mmu-miR-326-3p  0610007P14Rik
mmu-miR-330-5p  0610007P14Rik
mmu-miR-326-3p  Lmir
mmu-miR-330-5p  Lmir
mmu-miR-15      0610007P14Rik
mmu-miR-16      0610007P14Rik
mmu-miR-195     0610007P14Rik
mmu-miR-424     0610007P14Rik
mmu-miR-497     0610007P14Rik
mmu-miR-15-5p   0610007P14Rik
mmu-miR-16-5p   0610007P14Rik
mmu-miR-195-5p  0610007P14Rik
mmu-miR-424-5p  0610007P14Rik
mmu-miR-497-5p  0610007P14Rik
mmu-miR-6838-5p 0610007P14Rik
mmu-miR-15      Alinf
mmu-miR-16      Alinf
mmu-miR-195     Alinf
mmu-miR-424-5p  Alinf
mmu-miR-497     Alinf
mmu-miR-326     0610007P14Rik
mmu-miR-330-5p  0610007P14Rik
mmu-miR-326     0610007P14Rik
mmu-miR-330     0610007P14Rik
mmu-miR-1       Crgi
mmu-miR-206     Crgi
mmu-miR-613     Crgi
mmu-miR-1-3p    0610007P14Rik
mmu-miR-206     0610007P14Rik

여기에서 첫 번째 Miller 하위 명령은 nest슬래시에서 첫 번째 필드를 분할하고 다른 필드(이 경우 다른 필드 하나만)를 한 번 더 복사하여 레코드를 "중첩 해제" 또는 "폭발"하는 데 사용됩니다. 생성된 각 문자열에 대해 추가 로깅입니다.

두 번째 Miller 하위 명령은 put결과의 첫 번째 필드 값이 올바른 접두사 문자열로 시작하는지 테스트하고 그렇지 않은 경우 이를 추가합니다. 옵션은 Miller가 필드의 유형을 추론하는 것을 -S방지 put하고 모든 필드를 다음과 같이 처리합니다.텍스트.


질문에 대한 입력을 고려하면 awk다음과 같은 결과를 얻을 수 있습니다.

awk -F '\t' '
    BEGIN { OFS=FS }
    {
        nf = split($1,a,"/")
        
        print a[1], $2
        for (i = 2; i <= nf; ++i)
            print "mmu-miR-" a[i], $2
    }' file

또한 파일을 탭으로 구분된 파일로 읽고 첫 번째 필드를 슬래시로 분할하여 배열에 새로운 문자열 세트를 생성합니다 a. 그런 다음 첫 번째 생성된 문자열과 두 번째 필드를 인쇄한 다음 생성된 나머지 문자열을 반복하여 각 문자열 앞에 누락된 mmu-miR-접두사를 추가하고 두 번째 필드의 값을 사용하여 출력합니다.

관련 정보