잘림 문자를 사용하여 bash 인수 작성

잘림 문자를 사용하여 bash 인수 작성

\u2263양쪽에 두 개의 공백으로 구분된 유니코드 문자를 사용하여 bash 함수의 처음 두 인수를 인쇄하고 싶습니다 . 문제는 최종 유니코드가 70열에 표시되어야 한다는 것입니다. 문자 범위가 열 68에 $1도달 하면 $2추가 문자가 잘립니다.

         1         2         3   V     4         5         6         7
1234567890123456789012345678901234567890123456789012345678901234567890

 U  FIRST-ARG                                            SECOND-ARG  U
 U  FIRST-ARG-LONGGGGGGGGGGGGGGGG                        SECOND-ARG  U

가능한 최대 너비로 열 번호(예: 34문자로 설명되는 선택)를 지정할 수 있습니다.VFIRST-ARG

시작된 cl합계의 최대 길이입니다 cr.

local cl=34 cr=30
printf ' \u2263  %.${cl}s   %.${cr}s  \u2263\n' "$1" "$2"

답변1

은 공백 으로 채워 지고 63으로 잘립니다 bash.printf%-63.63s바이트문자가 아니므로 모든 문자가 싱글바이트가 아닌 이상 형식 지정/정렬에 사용할 수 없습니다. 99.99%의 문자가 여러 바이트를 사용하여 UTF-8로 인코딩됩니다. U+2263 문자는 UTF-8의 경우 3바이트, GB18030의 경우 4바이트로 인코딩됩니다.

ksh93과 마찬가지로 bash ${var:offset:length}는 문자 수준에서 복사하지만 모든 문자가 단일 너비인 경우에만 작동합니다.

텍스트를 올바르게 정렬하려면 가능한 방법은 다음과 같습니다.

  1. 문자 표시 너비를 고려하는 패딩/잘림 연산자를 사용하십시오.
  2. 출력이 터미널에 도달한다고 가정하고 제어 시퀀스를 사용하여 쓰기 위치에 원하는 것을 쓰고 그렇지 않은 것을 삭제하도록 터미널에 지시합니다.

1의 경우 bash 대신 내장 연산자(예: ksh93 또는 zsh)가 있는 셸을 사용할 수 있습니다.

zsh에서:

align() printf ' \u2263  %s  \u2263\n' ${(j[  ]mr[63])@}

인수 r[length]확장 플래그(여기서는 r[length][ ]공백이 기본 패딩 문자로 축약됨) right는 지정된 길이로 채워지고 m디스플레이 너비 단위의 길이와 함께 사용됩니다.

또는 나중에 명시한 대로 왼쪽 정렬(및 오른쪽 패딩) $1및 오른쪽 정렬입니다 .$2

align() printf ' \u2263  %s  \u2263\n' "${(mr[31])1} ${(ml[31])2}"

이를 사용하면 ksh93더욱 간단해집니다.

align() printf ' \u2263  %-63.63Ls  \u2263\n' "$1  $2"

%Ls이와 대조적으로 바이트 %s가 아닌 문자열을 사용하여 표시 너비에 따라 문자열을 채우고 자릅니다.

또는 왼쪽 $1과 오른쪽을 정렬합니다 $2.

align() printf ' \u2263  %-31.31Ls %31.31Ls  \u2263\n' "$1" "$2"

입력에 제어 문자가 포함되어 있으면 작동하지 않습니다.

2의 경우 자동 여백을 비활성화하고 전체 텍스트를 쓴 다음 68열로 이동한 다음 " ≣"나머지를 쓰고 지울 수 있습니다.

am_off=$(tput rmam) am_on=$(tput smam)
col68=$(tput cr; tput cuf 68)
del_to_eol=$(tput el)
align() {
  printf ' \u2263  %s\u2263%s\n' "$am_off$1  $2$col68  " "$del_to_eol$am_on"
}

답변2

2개의 긴 매개변수를 얻습니다.

set -- '123456789.123456789.123456789.123456789.' '987654321.987654321.987654321.987654321.'

V를 40으로 설정한다고 가정하면 field1에는 40자가 있고 field2에는 68-40=28자가 있습니다.

cl=40
cr=$((68-cl))

이제 우리는 첫 번째 필드를 왼쪽 정렬하고 두 번째 필드를 오른쪽 정렬하여 인쇄하려고 합니다(긴 인수에서는 보이지 않지만). printf 형식 문자열에서 필드 너비를 설정하는 것만으로는 충분하지 않으며 매개변수의 하위 문자열만 가져와야 합니다.

printf '\u2263  %-*s%*s  \u2263\n' "$cl" "${1:0:cl}" "$cr" "${2:0:cr}"
≣  123456789.123456789.123456789.123456789.987654321.987654321.98765432  ≣

우리는 그것을 볼 수 있습니다

  • "123456789.123456789.123456789.123456789.", 첫 번째 매개변수의 처음 40자
  • "987654321.987654321.98765432", 두 번째의 처음 28자입니다.

답변3

아? 뭐가 필요하세요?

문제가 문자열 길이를 조작하는 방법이라면 여기에 설명된 문자열 함수를 사용할 수 있습니다. https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Shell-Parameter-Expansion

형식화된 방식으로 무언가를 인쇄해야 하는 경우 C에서와 정확히 동일한 형식을 printf사용 echo합니다.printf()https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#index-printf

관련 정보