datamesh
파일의 행렬을 바꾸는 것과 같은 도구가 있지만 csv
문자를 기준으로 행과 열을 바꾸고 싶습니다. 그래서 파일
abcde
fghij
klmn
opqrs
되어야 한다
afko
bglq
chmq
dinr
ej s
3행이 더 짧기 때문에 마지막 행에 공백을 삽입해야 한다는 점에 유의하세요.
물론 이 작업을 수행하기 위해 C 프로그램을 작성할 수도 있지만 이 작업을 수행하는 도구를 발견한 적이 있지만 검색 엔진이 해당 도구를 찾는 데 도움을 줄 수 없었습니다.
답변1
rs
순수 transpose() 모드에서 유틸리티를 사용하여 이 작업을 수행할 수 있습니다 -T
. 먼저 입력의 간격을 적절하게 지정하는 경우입니다.
$ sed -e 's/./& /g' -e 's/ $//' file
a b c d e
f g h i j
k l m n
o p q r s
(또는 GNU sed가 있는 경우 이를 사용할 수 있습니다 sed 's/./ &/2g'
. 또 다른 옵션은 루프를 사용하는 것입니다 sed -E ':a; s/([^ ])([^ ])/\1 \2/; ta'
.)
$ sed -e 's/./& /g' -e 's/ $//' file | rs -Tng0
afko
bglp
chmq
dinr
ej s
중요한 옵션은 다음과 같습니다:
-T
순수 전치-n
빈 항목 채우기-g0
출력 여백 너비(열 간격)를 0으로 설정
awk
또는 입력 분할을 위해 빈 입력 필드 구분 기호와 기본 출력 필드 구분 기호를 사용합니다.
awk '{$1=$1} 1' FS= file | rs -Tng0
답변2
awk transpose를 사용한 일반적인 솔루션은 다음과 같습니다.
올바르게 작동하려면 열 수가 필요합니다.
이는 파일을 값 배열로 읽을 때 찾을 수 있습니다.
#!/bin/bash
file=i4
delimiter=""
sep=""
transpose() { : # comment sed for newer awks.
# Do this to separate characters in quite old awk
# very old wak does not allow that the FS could be Null.
#sed -e 's/./ &/g' "$file" |
awk '
{ for(i=1;i<=NF;i++){a[NR,i]=$i};{(NF>m)?m=NF:0} }
END { for(j=1; j<=m; j++)
{ for(i=1; i<=NR; i++)
{ b=((a[i,j]=="")?" ":a[i,j])
printf("%s%s",(i==1)?"":sep,b)
}
printf("\n")
}
}
' FS="$delimiter" sep="$sep" cc="$countcols" <"$file"
}
transpose
이 파일을 사용하면:
abc
fghij
klmn
opqrs
다음을 인쇄합니다:
afko
bglp
chmq
inr
j s
"필드 구분 기호"가 비어 있으면 awk가 문자 구분을 담당합니다. 변수도 비어 있으면
문자가 한 줄에 인쇄됩니다.sep
사용 가능한 awk가 오래된 경우 null FS는 효과가 없습니다. 다음 두 명령을 사용하십시오.
문자 수를 계산하려면 이전 버전의 awks에서는 다음을 사용합니다.
# Work with any POSIX awk to find the max character count in all rows.
countcols=$(awk '{l=length($0);(l>max)?max=l:0}END{print max}' < "$file")
바꾸려면 각 문자 앞에 공백을 추가하고 공백을 "필드 구분 기호"로 사용하고 빈 FS를 피할 수 있습니다.
sed -e 's/./ &/g' < "$file" |
awk ' {for(i=1;i<=cc;i++){if($i==""){$i=" "};r[i]=r[i]sep$i;};sep=""};
END{for(i=1;i<=cc;i++)print(r[i])}
' cc="$countcols"
최신 awk에 대한 sed 행을 주석 처리하십시오.
답변3
cut
다음은 및 를 사용한 솔루션 입니다 paste
. 구분 기호(예: 공백이나 탭)가 없으므로 몇 가지 수정이 필요합니다 sed
.
for COL in {1..5}; do cut -c $COL < infile | paste -s -d_ ; done | sed -e 's/__/_ /g' -e 's/_//g'
이는 여러 줄로 구분됩니다.
for COL in {1..5}; do
cut -c $COL < infile | paste -s -d_
done | sed -e 's/__/_ /g' -e 's/_//g'
첫 번째 부분의 출력은 다음과 같습니다.
for COL in {1..5}; do cut -c $COL < infile | paste -s -d_ ; done
a_f_k_o
b_g_l_p
c_h_m_q
d_i_n_r
e_j__s
한 가지 짜증나는 점은 시작하기 전에 열이 몇 개 있는지 알아야 한다는 것입니다.
답변4
줄의 문자 수가 적으면 각 줄을 일부 문자로 채우고 추가 문자를 삭제합니다.
echo abc | sed 's/./&@@@@/' sed -r 's/(.{4})./\1/'
알파벳@
echo ""| sed's/./&@@@@/'| sed -r's/(.{4})./\1/'
@@@@