NULL을 사용하여 표준 입력을 원하는 길이로 채우는 가장 좋은 방법

NULL을 사용하여 표준 입력을 원하는 길이로 채우는 가장 좋은 방법

다음과 같은 요구 사항이 있습니다. 고정 길이의 바이트로 잘라야 하는 입력 스트림이 있습니다. 입력 스트림의 길이를 미리 모릅니다. 스트림의 길이가 설정된 길이보다 작으면 0바이트로 채우고 싶습니다. 를 사용해 보았지만 truncate표준 입력이 아닌 파일만 처리할 수 있는 것 같습니다.

TEST예를 들어, 입력 스트림(stdin)이 이고 길이가 10바이트가 되기를 원한다고 가정해 보겠습니다 . 그런 다음 출력 스트림(stdout)은 TEST\x00\x00\x00\x00\x00.

이를 명확히 하기 위해 예제는 작은 문자열을 사용하여 수행되었지만 결과는 대규모 스트림(메가바이트에서 기가바이트까지)에서도 잘 수행되어야 합니다. 그리고 현재 제가 사용하고 있는 컨테이너는 Ubuntu 기반입니다.

답변1

GNU 사용 dd:

$ printf %s test | dd iflag=fullblock bs=10 status=none conv=sync count=1 | hexdump -C
00000000  74 65 73 74 00 00 00 00  00 00                    |test......|
0000000a

의 경우 ight 패딩(및 잘림) 인수 확장 플래그( 패딩 문자열의 확장 과 같은 이스케이프 시퀀스에 대한 플래그 )를 zsh사용합니다 .rp\0

$ string=test
$ printf %s ${(pr[10][\0])string} | hexdump -C
00000000  74 65 73 74 00 00 00 00  00 00                    |test......|
0000000a

하지만 10까지 패딩된다는 점에 유의하세요.수치, 10바이트가 아닙니다. multibyte이 옵션을 끄면( ) 이를 변경할 수 있습니다 set +o multibyte.

$ string=tést
$ printf %s ${(pr[10][\0])string} | hexdump -C
00000000  74 c3 a9 73 74 00 00 00  00 00 00                 |t..st......|
0000000b
$ printf %s ${(pr[10][\0])string} | wc -mc
     10      11
$ set +o multibyte
$ printf %s ${(bpr[10][\0])string} | hexdump -C
00000000  74 c3 a9 73 74 00 00 00  00 00                    |t..st.....|
0000000a
$ printf %s ${(bpr[10][\0])string} | wc -mc
      9      10

이러한 솔루션은 시스템 RAM 용량보다 큰 크기로는 확장이 잘 되지 않습니다.

@ilkkachu가 의견에서 제안한 것처럼 큰 크기의 경우

{ printf %s test; cat /dev/zero; } | head -c 1000000000

더 효율적입니다(표준은 아니지만 일반적이며 head -c한 번에 1바이트를 읽고 쓰는 것보다 훨씬 더 효율적입니다).dd bs=1

파일로 출력하는 경우 리소스 제한을 사용하여 다음을 자를 수도 있습니다.

(
  ulimit -f 1048576 # KiB
  printf %s test
  cat /dev/zero
) > file

답변2

다음 해결책을 찾았습니다.

echo -n 'TEST' | cat - /dev/zero | dd bs=1 count=10 2>/dev/null | hexdump

이것은 작동하고 다음을 올바르게 출력합니다.

0000000 4554 5453 0000 0000 0000
000000a

따라서 이것은 적어도 Linux에서는 작동하며 플랫폼 간 이식성은 신경 쓰지 않습니다. 하지만 dd내 목표를 달성하는 데 더 적합한 명령이 있을 수 있다고 생각합니다 .

관련 정보