printf 또는 echo를 사용하여 문자열 앞에 선행 문자를 추가하세요.

printf 또는 echo를 사용하여 문자열 앞에 선행 문자를 추가하세요.

문자열을 특정 길이로 채우기 위해 선행 문자를 추가하는 방법은 무엇입니까?

문자열이 20자보다 짧은 경우 문자열 앞에 0을 추가하고 싶다고 가정해 보겠습니다.

printf '%020s\n' "$line"

그러나 이는 0과 같은 다른 어떤 것도 아닌 선행 공백으로 문자열을 채웁니다.

문자열은 숫자와 기타 문자를 포함하는 임의의 문자열일 수 있습니다.

printf '%020i' $number문자열을 or 에 대한 숫자 + 나머지로 나누고 싶지 않습니다 printf '%020d $number'.

내 현재 출력은 다음과 같습니다

         shortstring

내가 원하는 출력은 다음과 같습니다.

000000000shortstring

답변1

수동으로 채워주시면 됩니다. POSIX 도구 사용을 고집한다면 이보다 더 간단한 해결책은 없다고 생각합니다.

while [ ${#line} -lt 20 ]; do
  line=0$line
done

또는

n=${#line}
while [ $n -lt 20 ]; do
  printf '0'
  n=$((n-1))
done
printf "$line\n"

물론 zsh에는 해당 구문이 있습니다. 위의 코드 조각과 달리 이 코드 조각은 문자열이 20자를 초과하는 경우 문자열을 자릅니다. 자르지 않으려면 문자열 끝을 추가할 수 있습니다.

print -r ${(l:20::0:)line}
print -r ${(l:20::0:)line}${line:20}

답변2

@Gnouc가 이미 지적했듯이 이미 절반쯤 왔습니다.

line='some chars'
printf '%0'$((20-${#line}))'d%s\n' 0 "$line"

###OUTPUT###
0000000000some chars

물론 줄이 20자를 초과하더라도 여전히 0을 얻게 됩니다.만약에 printf-형식 문자열의 대시를 올바르게 처리할 수 없기 때문에 오류가 발생하지 않습니다.(이것은 분명히 더 가능성이 높은 시나리오입니다). 하지만 이는 처리하기 쉽습니다.

printf "%.$((((l=20-${#line})>0)*l))d%s\n" 0 "$line"

형식 문자열은 printf'를 사용합니다.%.정확한%.0d플래그는 표시된 길이에 대해 분수 인수를 0으로 채웁니다. 그렇지 않으면 null 또는 null 정밀도의 경우 %.d앞에 오는 0을 표시된 숫자로 자릅니다. 이와 같이:

printf '#%.0d%c%.5d' 0000000 ':separator' 4 
#:00004

(참고: 이 %c형식은 연관된 인수의 첫 번째 문자를 인쇄합니다)

산술 $((표현식은 ))먼저 var를 $l20 마이너스로 설정한 다음 각각 0보다 작거나 크면 0 또는 1로 평가하고 ${#line}마지막으로 이를 곱합니다. 따라서 20-가 0보다 작으면 이렇게 하고, 0보다 크면 이렇게 합니다.$l$l${#line}$((0*l))$((1*l))

이 방법으로 당신은언제나20과 의 차이와 동일한 수의 선행 0만 인쇄합니다 ${#line}. 이와 같이:

line='some chars'
printf "#%.$((((l=20-${#line})>0)*l))d%s\n" 0 "$line"
#0000000000some chars

그리고...

line='some chars'
printf "#%.$((((l=4-${#line})>0)*l))d%s\n" 0 "$line"
#some chars

당신은 같은 것을 사용할 수 있습니다%.정확한fields 유형에도 동일하게 적용됩니다 s. 예를 들면 다음과 같습니다.

line='some chars'
printf "#%.$((((l=4-${#line})>0)*l))d%.4s\n" 0 "$line"
#some

...필요에 따라 잘라냅니다.

다음은 루프입니다. 다음은 5번 반복됩니다.

line=
until line=fivec$line; [ $((l)) -lt 0 ] 
do  printf "#%.$((((l=20-${#line})>0)*l))d%s\n" 0 "$line"
done    
#000000000000000fivec
#0000000000fivecfivec
#00000fivecfivecfivec
#fivecfivecfivecfivec
#fivecfivecfivecfivecfivec

표시된 0은 쉘 변수의 값에 전혀 포함되지 않으며(물론) $line형식 문자열이 지시하는 대로 자동으로 생성된다는 점에 주목할 가치가 있습니다.printf

더 정밀한 동일한 루프는 다음과 같습니다 %.20s.

line=
until line=fivec$line; [ $((l)) -lt 0 ] 
do  printf "#%.$((((l=20-${#line})>0)*l))d%.20s\n" 0 "$line"
done    
#000000000000000fivec
#0000000000fivecfivec
#00000fivecfivecfivec
#fivecfivecfivecfivec
#fivecfivecfivecfivec

그것으로 할 수 있는 또 다른 일은 정말 재미있습니다. printf0을 동적으로 생성하는 기능을 결합 하면 $IFS원하는 만큼 문자열을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

IFS=0 ; printf '10 lines\n%s' $(printf %010d) ; unset IFS 

###OUTPUT###
10 lines
10 lines
10 lines
10 lines
10 lines
10 lines
10 lines
10 lines
10 lines
10 lines

답변3

%s문자열 형식 사양입니다. 제로 패딩만디지털 변환을 위해 존재한다고 정의됨:

0d, i, o, u, x, .다른 변환의 경우 동작이 정의되지 않습니다.

$line숫자인 경우 다음을 사용하십시오.

printf '%020i\n' $line

원하는 결과(또는 다른 숫자 형식 지정자 중 하나)를 얻으려면 값이 더 복잡하지만 숫자로 시작하는 경우 다음을 사용할 수 있습니다.

printf '%020i %s\n' $num $restofline

숫자와 문자열을 한번에 결합해보세요.

답변4

사용할 수 있는 경우 perl:

$ perl -e 'print sprintf "%020s\n","shortstring"'
000000000shortstring

보다 일반적인 경우:

$ perl -e 'print sprintf "%020s\n",shift' shortstring
000000000shortstring

$ perl -e 'print sprintf "%020s\n", $_ for @ARGV' shortstring qwerty
000000000shortstring
00000000000000qwerty

노트

일부 플랫폼에서는 적어도 를 AIX사용할 때 앞에 0을 사용하여 출력 문자열의 형식을 지정할 수 있으며 GNU gcc컴파일할 때 경고가 표시됩니다.

$ cat test.c
#include <stdio.h>

int main() {
    printf("%08s\n", "qwerty");
    return 0;
}

그 다음에:

$ gcc -Wall test.c
test.c: In function ‘main’:
test.c:4:5: warning: '0' flag used with ‘%s’ gnu_printf format [-Wformat]

이를 사용하고 싶지 않다면 다음을 perl시도해 보세요.

$ line=shortstring
$ printf "%0$((20-${#line}))d%s"  0  $line
000000000shortstring

문자열 길이가 20보다 큰 경우 이 메서드는 이를 처리할 수 없습니다. @mikeserv 응답을 사용하여 문제를 처리하거나 이전에 확인하는 데 사용할 수 있습니다 printf.

관련 정보