UNIX에서 열을 가운데 정렬하는 방법은 무엇입니까?

UNIX에서 열을 가운데 정렬하는 방법은 무엇입니까?

명령을 사용하여 열을 가운데 정렬하려고 합니다 column.

출력은 다음과 같아야 합니다.

temperatures  
    50  
    12  
    89  
    63  

어떻게 해야 하나요?

답변1

나는 당신이 그 명령을 사용하기를 원한다는 것을 알기 전에 이 대답을 썼지 column만, 그것이 필요하지 않다면 다음 bash쉘 스크립트를 사용하여 텍스트를 가운데에 맞출 수 있습니다:

#!/bin/bash
set -e    # exit the script if something goes wrong

width=12
data="temperatures 50 12 89 63"

for word in $data; do
    strlen=$(printf $word | wc -c)
    w=$(( ($width - $strlen)/2 ))
    printf "%${w}s%s\n" "" $word
done

작동 방식:

  • $width열 너비입니다
  • for인쇄된 각 단어를 반복합니다 .$data
  • $strlen현재 단어의 길이(바이트)입니다.
  • $w중심에 놓을 단어 앞에 인쇄되는 공백 수입니다.
  • printf$w공백 다음에 단어를 인쇄하세요 .

산출:

temperatures
     50
     12
     89
     63

이 스크립트는 단일 바이트 텍스트 인코딩에서만 작동합니다. strlen포함을 처리하려면 이 줄을 변경해야 합니다.

답변2

일부 파일이 주어지면

temps,temperatures,heatness
500,50,50
1212,12,12
899,89,8989
63,6363,63

column명령은 정렬된 열을 제공하지만 다른 특별한 조정은 제공하지 않습니다.

$ column -t -s, file
temps         temperatures  heatness
500           50            50
1212          12            12
899           89            8989
63            6363          63

작은 awk스크립트를 사용하여 센터링을 수행할 수 있습니다.

$ awk -F, -f center-cols.awk file
temps temperatures heatness
 500       50         50
1212       12         12
 899       89        8989
 63       6363        63
$ awk -F, -v OFS='|' -f center-cols.awk file
temps|temperatures|heatness
 500 |     50     |   50
1212 |     12     |   12
 899 |     89     |  8989
 63  |    6363    |   63

스크립트 center-cols.awk는 다음과 같습니다.

function center(w, string,         space, before, after) {
    space  = w - length(string)  # number of spaces in total to fill
    before = int(space/2)        # spaces before string
    after  = space - before      # the rest of spaces after
    return sprintf("%*s%s%*s", before, "", string, after, "")
}

FNR == 1 {
    for (i = 1; i <= NF; ++i)
        width[i] = length($i)
}

{
    for (i = 1; i <= NF; ++i)
        $i = center(width[i], $i)

    print
}

이 스크립트는 각 행의 머리글 열(첫 번째 행) 너비를 기준으로 데이터의 각 열을 중앙에 배치합니다. 이는 헤더보다 긴 데이터가 있는 행이 여전히 잘못 정렬됨을 의미합니다. 이러한 제한으로 인해 스크립트 구현이 단순화됩니다. 그렇지 않으면 파일을 두 번 구문 분석해야 합니다. 한 번은 각 열의 최대 열 너비를 찾고 한 번은 데이터 형식을 다시 지정해야 합니다.

스크립트는 먼저 각 헤더 열의 너비를 가져와서 width배열에 저장합니다. 그런 다음 해당 center함수를 사용하여 각 열을 다시 작성합니다.

center함수는 너비와 문자열을 사용하여 해당 너비를 중심으로 하는 문자열을 반환하며 양쪽에 공백이 사용되지 않은 공간을 채웁니다. 결과 문자열은 sprintf()측면 공백으로 작성된 형식 지정자를 사용하여 구성 됩니다 %*s. 이 지정자는 너비와 문자열을 사용하며 계산된 너비와 실제 데이터의 앞뒤 공백이 있는 빈 문자열을 제공합니다(빈 문자열은 지정된 너비로 형식화됩니다).

행의 모든 ​​열 형식이 다시 지정되면 행이 인쇄됩니다.


파일을 두 번 구문 분석하면 각 열의 최대 너비를 찾을 수 있습니다. 이렇게 하면 열 너비를 정의하기 위해 머리글 행에 의존할 필요가 없습니다.

function center(w, string,         space, before, after) {
    space  = w - length(string)  # number of spaces in total to fill
    before = int(space/2)        # spaces before string
    after  = space - before      # the rest of spaces after
    return sprintf("%*s%s%*s", before, "", string, after, "")
}

NR == 1 {
    for (i = 1; i <= NF; ++i)
        width[i] = length($i)
    next
}

FNR == NR {
    for (i = 1; i <= NF; ++i)
        if (width[i] < length($i))
            width[i] = length($i)
    next
}

{
    for (i = 1; i <= NF; ++i)
        $i = center(width[i], $i)

    print
}

짧은 열 헤더가 있는 파일에 대해 다음 명령을 실행합니다.

$ awk -F, -v OFS='|' -f center-cols.awk file file
 t  | a  | b
500 | 50 | 50
1212| 12 | 12
899 | 89 |8989
 63 |6363| 63

명령줄에서 파일 이름을 두 번 지정해야 합니다.

관련 정보