구문 분석할 파일이 있습니다.
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-
접두사를 추가하고 두 번째 필드의 값을 사용하여 출력합니다.