UNIX 명령을 사용하여 문자열을 새 줄과 작은따옴표로 정렬

UNIX 명령을 사용하여 문자열을 새 줄과 작은따옴표로 정렬

다음과 같은 텍스트가 많이 있습니다.

K1      CM1     TN1     CT14    D01
K2      CM2     TN2     CT15    D02
K3      CM3     TN3     CT16    D03
K4      CM4     TN4     CT17    D04
K5      CM5     TN5     CT18    D05
K6      CM6     TN6     CT19    D06
K7      CM11    TN7     CT20    D07
K8      CM12    TN8             D08
TW10    CM15    TN9             D09
TW11            TN10            D11
TW12            TN11            D12
TW16            TN12            D6W

(열은 비어 있을 수 있으며 공백이 아닌 탭으로 구분할 수 있습니다. - cas)

BBedit의 Run Unix 명령 기능을 사용하여 이 텍스트를 다음과 같이 변환하고 싶습니다.

'K1',
'K2',
'K3',
'K4',
'K5',
'K6',
'K7',
'K8',
'TW10',
'TW11',
'TW12',
'TW16',
'CM1',
'CM2',
'CM3',
'CM4',
'CM5',
'CM6',
'CM11',
'CM12',
'CM15',
'TN1',
'TN2',
'TN3',
'TN4',
'TN5',
'TN6',
'TN7',
'TN8',
'TN9',
'TN10',
'TN11',
'TN12',
'CT14',
'CT15',
'CT16',
'CT17',
'CT18',
'CT19',
'CT20',
'D01',
'D02',
'D03',
'D04',
'D05',
'D06',
'D07',
'D08',
'D09',
'D11',
'D12',
'D6W'

보시다시피, 각 문자열은 작은따옴표로 묶이고 최종 문자열과 구분되며 그 뒤에 쉼표가 옵니다.

미리 감사드립니다.

답변1

입력에 탭으로 구분된 필드가 있는 줄이 있고 먼저 위에서 아래로 각 줄의 첫 번째 필드가 필요하고 두 번째 필드 등이 필요하고 따옴표와 쉼표가 필요하다고 가정하면 다음과 같은 저렴한 솔루션이 있습니다.

최대 9개의 열이 있는 보기 흉한 두 행(sed를 사용하여 형식화됨):

for i in 1 2 3 4 5 6 7 8 9; do cut -f$i file.txt; done | 
    grep -v '^$' | sed  -e "s/^/'/" -e "s/\$/'/" -e '$!s/$/,/'

AWK를 사용한 수동 전치(마지막 쉼표를 제거하기 위해 sed 추가):

awk -F'\t' 'NF > cols {cols=NF}
                      {for (i=1; i<=NF; i++) { a[i,NR]=$i }} 
            END { for (j=1;j<=cols;j++) for (i=1;i<=NR;i++)
                      if (a[j, i] != "") printf "\047%s\047,\n", a[j, i] }' file.txt |
    sed -e '$s/,$//'

GNU datamash 사용(및 포맷을 위한 sed):

datamash --no-strict transpose < file.txt | tr -s '\t' '\n' |
    sed -e "s/^/'/" -e "s/\$/'/" -e '$!s/$/,/'

(Linux에서 테스트되었으며 처음 두 개는 macOS에서도 작동합니다)

답변2

grep과 sed를 사용해 볼 수도 있습니다.

for i in K TW CM TN CT D ;do grep -ow $i[0-9]*[A-Z]* <input_file;done

각 항목을 작은따옴표로 묶고 각 줄 끝에 쉼표를 추가하려면 위의 내용을 다음 명령에 파이프하세요.

sed "s/$/\'\,/" | sed "s/^/\'/"

답변3

이것이 무엇을 의미하는지 잘 모르겠지만 the Run Unix command feature in BBedit표시된 입력을 기반으로 표시되는 출력을 생성하기 위해 Unix 명령을 찾고 있다면 awk를 사용하고 필드가 탭으로 구분되어 있다고 가정하십시오.

$ cat tst.awk
BEGIN { FS="\t" }
{
    for ( i=1; i<=NF; i++ ) {
        if ( $i != "" ) {
            a[i,NR] = $i
            max_j[i] = NR
        }
    }
    max_i = (max_i > NF ? max_i : NF)
}
END {
    for ( i=1; i<=max_i; i++ ) {
        for ( j=1; j<=max_j[i]; j++ ) {
            printf "%s\047%s\047", sep, a[i,j]
            sep = ",\n"
        }
    }
    print ""
}

$ awk -f tst.awk file
'K1',
'K2',
'K3',
'K4',
'K5',
'K6',
'K7',
'K8',
'TW10',
'TW11',
'TW12',
'TW16',
'CM1',
'CM2',
'CM3',
'CM4',
'CM5',
'CM6',
'CM11',
'CM12',
'CM15',
'TN1',
'TN2',
'TN3',
'TN4',
'TN5',
'TN6',
'TN7',
'TN8',
'TN9',
'TN10',
'TN11',
'TN12',
'CT14',
'CT15',
'CT16',
'CT17',
'CT18',
'CT19',
'CT20',
'D01',
'D02',
'D03',
'D04',
'D05',
'D06',
'D07',
'D08',
'D09',
'D11',
'D12',
'D6W'

답변4

펄 사용:

$ perl -lne '
    # split each input line on single tabs (not one-or-more
    # whitespace chars) into temporary array @F.
    @F = split /\t/;

    # Construct an Array-of-Arrays (AoA) containing the data.
    # This works with any number of columns, not limited to 5.
    # Assumes each input line has the same number of fields,
    # although some may be empty.
    foreach my $i (keys @F) {
        if (length($F[$i]) > 0) {
          push @{$columns[$i]}, "\047" . $F[$i] ."\047" ;
        };
    };

    END {
        # flatten the AoA with map and print it
        print join(",\n", map { @$_ } @columns);
    }' input.txt 
'K1',
'K2',
'K3',
'K4',
'K5',
'K6',
'K7',
'K8',
'TW10',
'TW11',
'TW12',
'TW16',
'CM1',
'CM2',
'CM3',
'CM4',
'CM5',
'CM6',
'CM11',
'CM12',
'CM15',
'TN1',
'TN2',
'TN3',
'TN4',
'TN5',
'TN6',
'TN7',
'TN8',
'TN9',
'TN10',
'TN11',
'TN12',
'CT14',
'CT15',
'CT16',
'CT17',
'CT18',
'CT19',
'CT20',
'D01',
'D02',
'D03',
'D04',
'D05',
'D06',
'D07',
'D08',
'D09',
'D11',
'D12',
'D6W'

@columns이는 입력을 한 줄씩 읽고, 단일 탭 문자를 구분 기호로 사용하여 각 줄을 분할하고, 작은따옴표(8진수)로 묶인 각 줄의 null이 아닌 열에서 호출되는 배열 배열을 구성합니다 \047.

전체 파일을 읽었을 때 map"평탄화"(즉, 단일 배열로 변환)를 사용하고 ,\n각 요소 사이에 인쇄합니다.


그런데, map목록/배열에 대한 작업을 수행하기 위한 내장 Perl 함수입니다. 특이한 특수 for루프라고 생각하면 됩니다. perldoc -f map자세히보다. perldoc -f splitPerl의 기능에 익숙하지 않은 경우에도 split읽어보면 유용할 것입니다 . 게다가 perldoc -f join.

관련 정보