모든 해당 값에 대해 행을 반복하고 싶습니다. 어떤 도움이라도
내 입력 파일은 다음과 같습니다
pos COL1 COL2 COL3
18691441 C A G
18691572 G C G
18691620 A T G
18691716 C G C
나는 이런 출력을 원한다
pos COL1
18691441 COL1 C
18691441 COL2 A
18691441 COL3 G
18691572 COL1 G
18691572 COL2 C
18691572 COL3 G
18691620 COL1 A
18691620 COL2 T
18691620 COL3 G
18691716 COL1 C
18691716 COL2 G
18691716 COL3 C
행을 반복하려고 하는데 계속 반복됩니다.
while read line; do for i in {1..3}; do echo "$line"; done; done < real2.txt
출력을 제공합니다.
pos COL1 COL2 COL3
18691441 C A G
18691441 C A G
18691441 C A G
18691572 G C G
18691572 G C G
18691572 G C G
18691620 A T G
18691620 A T G
18691620 A T G
18691716 C G C
18691716 C G C
18691716 C G C
그런 다음 입력된 1.txt 파일에서 pos를 추출하여 1_pos.txt를 만들고 다음과 같이 작성했습니다.
pos
18691441
18691572
18691620
18691716
for i in `cat 1_post.txt`;
do
x=$(grep -i "^$i" 1.txt | awk 'FNR == 1 {print $1"\t""COL1""\t"$2}' ) ;
y=$(grep -i "^$i" 1.txt | awk 'FNR == 1 {print $1"\t""COL2""\t"$3}' ) ;
z=$(grep -i "^$i" 1.txt | awk 'FNR == 1 {print $1"\t""COL3""\t"$4}' ) ;
echo -e "$x""\n""$y""\n""$z";
done
이렇게 하면 열 정보가 포함된 출력이 제공되지만 3개가 아닌 405개의 열이 있는 경우 각 열에 대해 행을 405번 반복하고 싶지 않아 루프에 넣으려고 했지만 작동하지 않습니다.
18691441 COL1 C
18691441 COL2 A
18691441 COL3 G
18691572 COL1 G
18691572 COL2 C
18691572 COL3 G
18691620 COL1 A
18691620 COL2 T
18691620 COL3 G
18691716 COL1 C
18691716 COL2 G
18691716 COL3 C
답변1
어때요?
while read line col1 col2 col3;
do
if [[ "$line" = "pos" ]]; then
echo "pos COL"
continue
fi
echo "$line COL1 $col1"
echo "$line COL2 $col2"
echo "$line COL3 $col3"
done < real2.txt
산출:
pos COL
18691441 COL1 C
18691441 COL2 A
18691441 COL3 G
18691572 COL1 G
18691572 COL2 C
18691572 COL3 G
18691620 COL1 A
18691620 COL2 T
18691620 COL3 G
18691716 COL1 C
18691716 COL2 G
18691716 COL3 C
답변2
앗방법:
awk 'BEGIN{OFS="\t";print "pos" OFS "COL1"}{if(NR==1){for(f=2;f<=NF;f++) c[f]=$f;}
else{for(i=2;i<=NF;i++) print $1,c[i],$i}}' real2.txt
산출:
pos COL1
18691441 COL1 C
18691441 COL2 A
18691441 COL3 G
18691572 COL1 G
18691572 COL2 C
18691572 COL3 G
18691620 COL1 A
18691620 COL2 T
18691620 COL3 G
18691716 COL1 C
18691716 COL2 G
18691716 COL3 C
OFS="\t"
- 출력 필드 구분 기호
print "pos" OFS "COL1"
- 인쇄머리글철사
if(NR==1){for(f=2;f<=NF;f++) c[f]=$f;
- 첫 번째 행/헤더 행에서 열 이름 수집
for(i=2;i<=NF;i++) print $1, c[i], $i
COL...
pos
- 해당 열 값과 해당 열 이름을 기준으로 각 열( ) 값을 "행 단위"로 인쇄합니다 .
답변3
이것은 awk
작업에 적합한 도구입니다. 하지만 한 번만 호출하면 됩니다.
awk -v OFS='\t' '
NR == 1 {print $1, "name", "value"; split($0, header); next}
{for (i = 2; i < NF; i++) print $1, header[i], $i}' < your-file
(변형로마인의 대답)
답변4
while IFS= read -r l; do
read -r -a A <<<"$l"
case $l in
'pos'[\ \ ]* )
echo "${A[@]:0:2}"
C=("${A[@]:1}")
;;
* )
p=0 x=${A[0]}
for e in "${A[@]:1}"; do
echo "$x ${C[$p]} $e"
((p++))
done
;;
esac
done < yourfile
sed -E '
/\n/bloop
y/\t/ /;s/ +/ /g;s/^ +//;s/ +$//
1{
h
s/ /\n/2
x
s/ /\n/;s/.*\n//
x
s/\n.*//
b
}
G;s/\n/ &/
:loop
# 1 2 3 4 5
s/^(\S+ )(\S+) (.*)(\n)(\S+) ?/\1\5 \2\4\1\3\4/
/\n$/{
/\n.*\n/!d
}
P
/\n.*\n/D
tloop
' yourfile
결과
pos COL1
18691441 COL1 C
18691441 COL2 A
18691441 COL3 G
18691572 COL1 G
18691572 COL2 C
18691572 COL3 G
18691620 COL1 A
18691620 COL2 T
18691620 COL3 G
18691716 COL1 C
18691716 COL2 G
18691716 COL3 C
설명하다
- 먼저 나머지 모든 탭을 공백으로 변환한 다음 여러 공백을 압축하고 마지막으로 모든 선행/후행 공백을 잘라냅니다.
- 첫 번째 줄에 대해 특별한 처리를 수행합니다.
- a) 라인을 복사합니다.
- b) 나중에 사용할 수 있도록 두 번째 열의 끝을 표시합니다.
- c) 이 표시된 행을 예약된 공간에 저장된 복사본으로 바꿉니다.
- d) 첫 번째 열을 제거하고 cols1,2의 & 표시를 복원합니다.
- 다른 모든 행(2~eof)의 경우 열 이름을 행에 추가합니다.
do-while
그런 다음 반복할 때마다 표시된 방식으로 필드를 다시 정렬하여 열 이름과 해당 값이 인쇄되도록 하는 루프를 설정합니다 . 줄의 끝이 보이고 그 줄에 남은 유일한 문자가 보이면 멈춥니다\n
.\n
그렇지 않으면 앞부분을 잘라내고 루프의 시작 부분으로 다시 분기합니다.