문자를 기준으로 텍스트 파일을 바꾸는 방법

문자를 기준으로 텍스트 파일을 바꾸는 방법

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/'

@@@@

관련 정보