같은 행에 있는 이름을 별도의 쌍으로 분리하고 싶습니다.
TMPRSS2|pp9284 AADAT Sample1
ERG TMPRSS2|pp9284 Sample2
TMPRSS2|pp9284 ETV1 Sample3
PDE4A MIA|MIA-RAB4B|RAB4B|RAB4B-EGLN2|EGLN2 Sample4
이것은 아마도
TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG TMPRSS2 Sample2
ERG pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4
두 열 모두에 여러 이름이 있으므로 별도의 쌍이 필요합니다. 별도의 쌍이 있는 후에 다른 테이블과 비교하고 싶기 때문에 이를 위해 mysql을 사용해 보았습니다. R의 strsplit은 여러 이름의 수가 고정된 경우에만 작동합니다. 하지만 행마다 다릅니다. sed, awk를 사용하여 이 작업을 수행할 수 있나요?
값이 동일하게 유지되는 특정 열도 있으며 기본적으로 동일한 행 내의 값은 동일하게 유지됩니다. 이 열을 어떻게 인쇄해야 합니까? 세 번째 열을 추가했는데 해당 값이 새 행에 복사되었습니다. 이를 위해 for 루프에서 print $3 을 사용하여 인쇄했지만 작동하지 않습니다.
답변1
$ awk '{split($1,a,"|"); split($2,b,"|"); for (i in a) {for (j in b) print a[i],b[j];}}' file
TMPRSS2 AADAT
pp9284 AADAT
ERG TMPRSS2
ERG pp9284
TMPRSS2 ETV1
pp9284 ETV1
PDE4A RAB4B-EGLN2
PDE4A EGLN2
PDE4A MIA
PDE4A MIA-RAB4B
PDE4A RAB4B
세 번째( SampleN
) 필드를 동시에 인쇄하려면 $3
루프 내부에 인쇄 문을 추가하기만 하면 됩니다.
$ awk '{split($1,a,"|"); split($2,b,"|"); for (i in a) {for (j in b) print a[i],b[j],$3;}}' file
TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG TMPRSS2 Sample2
ERG pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
답변2
배시 사용:
# important to use parentheses, not braces, to localize changes to IFS
# the variable is purposefully unquoted
split_pipe() ( IFS='|'; echo $1 )
while read -r first second third; do
for word1 in $(split_pipe "$first"); do
for word2 in $(split_pipe "$second"); do
echo $word1 $word2 $third
done
done
done < file
답변3
GNU를 사용하면 sed
다음을 수행할 수 있습니다.
sed -E 's/(\|[^ |]+) /\1| /
s/(([^|]* )?([^|]*))\|(([^ ]*)(.*))/\1\6\n\2\4/
/\n/P;D' <infile
...인쇄...
TMPRSS2 AADAT Sample1
pp9284 AADAT Sample1
ERG TMPRSS2 Sample2
ERG pp9284 Sample2
TMPRSS2 ETV1 Sample3
pp9284 ETV1 Sample3
PDE4A MIA Sample4
PDE4A MIA-RAB4B Sample4
PDE4A RAB4B Sample4
PDE4A RAB4B-EGLN2 Sample4
PDE4A EGLN2 Sample4
\n
한 줄의 내용을 분할하고 인쇄한 다음 추가 줄 문자를 하나씩 제거하는 방식으로 작동합니다 . 이 P
명령은 패턴 공간에서 처음으로 나타나는 ewline P
만 인쇄하므로 \n
필요한 경우 편집 버퍼의 일부만 쉽게 인쇄할 수 있습니다.
이 경우 sed
모든 비트는 공백을 포함하지 않는 파이프의 분할된 각 부분에 대해 편집 버퍼의 양쪽 끝에 두 번 배치됩니다. sed
가장 왼쪽 파이프 분할의 왼쪽과 오른쪽에 가장 왼쪽과 가장 오른쪽 끝을 삽입하고 순서대로 ewline을 사용한 \n
다음 오른쪽에 남아 있는 모든 파이프 분할의 양쪽 끝에 동일한 선택 항목을 삽입합니다. 라인의 손 쪽을 삽입합니다 \n
. 따라서 패턴 공간에 ewline이 존재한다면 왼쪽 비트만 인쇄한 다음 패턴 공간에서 처음 나타나는 ewline만 삭제하고 다시 시도하면 됩니다 sed
.P
\n
D
\n
첫 번째 교체는 한 번만 발생합니다. 파이프로 구분된 섹션의 끝에 파이프를 추가하기 때문에 마지막 발생의 경우에도 항상 구분할 파이프가 있습니다. 나머지 시간에는 sed
교체가 이루어지며 s///
패턴 P
공간의 첫 번째 줄을 인쇄하고 D
동일한 삭제가 이어집니다. 더 이상 그렇게 할 수 없으면 D
삭제 됩니다.모두패턴 공간을 확보하고 자동으로 다음 입력 라인을 가져옵니다.
동일한 작업을 수행하도록 POSIX BRE를 작성할 수 있습니다.
sed ' s/\(|[^ |]\{1,\}\) /\1| /
s/^\(\( *[^ |]* *\)*\([^ |]*\)\)|\(\([^ ]*\)\(.*\)\)/\1\6\
\2\4/; /\n/P;D' <infile