쉘 함수는 첫 번째 인수를 중앙에 둡니다.

쉘 함수는 첫 번째 인수를 중앙에 둡니다.

나노 텍스트 편집기에서 선택 항목을 명령으로 전송할 수 있으며 종종 텍스트를 중앙에 배치해야 하므로 다음 코드를 생각해 냈습니다.

center() {
  str=$1
  # Strip leading and trailing whitespace from the string
  str=$(echo "$str" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
  str_len=${#str}
  margin=$(((80 - str_len) / 2))
  printf "%*s%s%*s\n" $margin "" "$str" $margin ""
}

하지만 저는 스크립팅에 대해 잘 모르기 때문에 이 코드를 개선하는 방법을 알고 싶습니다.

Bash 솔루션에 연결하는 이유는 무엇입니까? 나는 이 쉘을 사용하지 않습니다. 단지 sh와 함께 실행되기를 원합니다.

답변1

쉘을 사용한다고 가정하면 bash(그렇지 않은 경우 이 답변의 끝 참조) bash표준 변수 확장 및 확장 와일드카드 패턴(하나 이상의 공백 유사 문자와 일치)을 사용하여 문자열에서 측면 공백을 보다 효율적으로 제거할 수 있습니다.str+([[:space:]])

shopt -s extglob

str=$1
str=${str##+([[:space:]])}  # strip at start
str=${str%%+([[:space:]])}  # strip at end

(로 주어진 열에 오른쪽 정렬하여 인쇄하고 싶습니다.+에스)/2 중는 터미널의 너비입니다(출력에 따라 tput cols, 그러나 사용할 수도 있음 $COLUMNS).에스문자열의 길이입니다( ${#str}).

printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"

기능:

center () (
    shopt -s extglob

    str=$1
    str=${str##+([[:space:]])}
    str=${str%%+([[:space:]])}

    printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
)

함수의 본문은 서브쉘입니다. 이렇게 하면 extglob셸 옵션 설정이 호출 셸로 넘치지 않습니다.

종속성 없음 extglob(모든 에 적용 sh):

center () {
    str=$(printf '%s\n' "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
    printf '%*s\n' "$(( ( $(tput cols) + ${#str} ) / 2 ))" "$str"
}

정적 80 열 너비로 형식을 지정하려면 $(tput cols)로 바꾸십시오.80

답변2

사이에 여러 개의 공백이 연결되어 있지 않은 경우 다음 명령을 사용하여 트리밍을 단순화할 수 있습니다.str=$(echo $1)

center () {
  str=$(echo $1)
  len=${#str}
  margin=$((($COLUMNS - len) / 2))
  printf "%${margin}s%s\n" " " "$str"
}

뒤에 공백을 추가할 필요가 없습니다 $str.

관련 정보