을 사용하는 것을 알고 있지만 tail -c +N
매우 느리고 하나의 CPU 코어를 고정합니다.
leijurvs-MacBook-Pro:Downloads leijurv$ time cat /dev/zero | head -c 100000000 | shasum -a 256
a993f8c574e0fea8c1cdcbcd9408d9e2e107ee6e4d120edcfa11decd53fa0cae -
cat /dev/zero 0.00s user 0.02s system 4% cpu 0.471 total
head -c 100000000 0.01s user 0.03s system 9% cpu 0.470 total
shasum -a 256 0.45s user 0.02s system 99% cpu 0.469 total
leijurvs-MacBook-Pro:Downloads leijurv$ time cat /dev/zero | head -c 100000000 | tail -c +2 | shasum -a 256
f4be792b71a024a60d77b3ac4c1c2b88ac51480fa25f88d10865827f8c086506 -
cat /dev/zero 0.01s user 0.03s system 0% cpu 7.241 total
head -c 100000000 0.02s user 0.03s system 0% cpu 7.240 total
tail -c +2 7.20s user 0.03s system 99% cpu 7.247 total
shasum -a 256 0.51s user 0.04s system 7% cpu 7.247 total
leijurvs-MacBook-Pro:Downloads leijurv$
head
매우 좋은. 나는 shasum을 사용하여 처음 100MB에 대해 0을 얻었습니다 head
. 0.47초가 걸렸습니다.
tail -c +2
예전에는 첫 번째 바이트를 건너뛰곤 했는데 갑자기 7.2초가 걸렸습니다.
tail
이 시간 동안 하나의 CPU 코어가 고정됩니다.
내가 어떻게 할 수있는표현적으로스트림의 처음 N바이트를 건너뛰시겠습니까?
답변1
파일을 입력하기 전에 파일의 첫 번째 바이트를 건너뛰려면 shasum
다음을 수행할 수 있습니다( 출력 형식이 이것이 사용 중인 쉘임을 나타내기 zsh
때문에 여기에 사용된 구문 ).time
time cat /dev/zero | head -c 100000000 |
(LC_ALL=C read -u0 -k1 && shasum -a 256)
이는 추가 프로세스가 없으며 첫 번째 바이트가 파이프에서 읽혀짐을 의미합니다.read
시작하기 전에 shasum
.
그게 LC_ALL=C read -u0 -k1
바로 read
ing 1
문자입니다( k
여기서는열쇠처음에는 read -k
키 입력이 터미널에서 읽혀집니다. 여기서 문자는 LC_ALL=C
파일 설명자 u
니트 번호 0
(stdin; 여기서는 터미널이 아닌 스트림에서 읽는다는 점을 분명히 하기 위해) 덕분에 단일 바이트입니다.
쉘을 사용하면 bash
다음과 같습니다.read
명령은 입니다 LC_ALL=C IFS= read -rd '' -n1
.
zsh에 해당하는 것은 read -k
일반적으로 이지만 read -N
NUL 바이트를 포함하는 입력에는 작동하지 않으며 bash
단지 read
스트라이핑일 뿐입니다(또한 -N
ksh93에서 복사한 것은 상대적으로 새로운 추가 항목으로 macos에 있는 고대 버전의 bash에서는 사용할 수 없습니다). 구분자를 NUL 바이트(여기서는 빈 문자열로 표시됨)로 설정 하여 d
이를 방지할 수 있습니다 . 첫 번째 NUL로 구분된 레코드에서 한 문자를 읽는 것입니다 -n1
(다시 바이트를 생성하여). LC_ALL=C
그러나 이는 와 같은 다른 바이트 수에 적응하지 않는다는 것을 의미합니다 -rd '' -n2
. 첫 번째 바이트가 0이면 바이트를 건너뜁니다.
다른 셸의 경우 read
명령을 dd bs=1 count=1 > /dev/null 2>&1
(change , 1바이트 이상 건너뛰지 count
마세요 )로 바꿀 수 있습니다. 또한 함께 작동합니다bs
head -c 1 > /dev/null
일부head
비표준 옵션을 지원 하지만 -c
전부는 아니지만(특히 FreeBSD가 아니므로 아마도 macOS는 아닐 수도 있음) 일부는 더 적은 바이트의 출력이 요청되더라도 고정 크기 청크로 입력을 읽습니다. 그러나 위의 내용과 달리 read
해당 1바이트를 읽을 수 없을 때 실패 종료 상태를 보고하지 않으므로 shasum
어떤 경우에도 실행됩니다.
체크섬이 파이프 대신 일반 파일인 경우 다음을 수행할 수 있습니다.줄넘기더 효율적입니다(여러 바이트를 건너뛰어야 한다고 가정).구하다파일에서 건너뛸 부분을 읽고 삭제하는 대신(스틸 zsh
구문):
zmodload zsh/system
{ sysseek 1234567 && shasum -a 256; } < some-big-file
처음 1234567바이트를 건너뜁니다.
또는 ksh93을 사용하십시오.
shasum -a 256 < some-big-file <#((1234567))
다른 껍질과일부dd
(저는 macOS 구현을 모릅니다) 다음을 수행할 수 있습니다.
{ dd bs=1 skip=1234567 count=0 2> /dev/null; shasum -a 256; } < some-big-file
그러나 count=0
휴대용으로 사용할 수는 없습니다. count가 0일 때 모든 dd
구현이 여기에서 작업을 수행하는 것은 아닙니다. 일부에서는 이렇게 해석하기도 합니다.lseek()
count=infinity
답변2
Mac OSX는 tail
느립니다.
brew install coreutils
gtail
그런 다음 문제 해결을 위해 전환하십시오 .
leijurvs-MacBook-Pro:~ leijurv$ time cat /dev/zero | head -c 100000000 | tail -c +2 | shasum -a 256
f4be792b71a024a60d77b3ac4c1c2b88ac51480fa25f88d10865827f8c086506 -
cat /dev/zero 0.01s user 0.03s system 0% cpu 7.153 total
head -c 100000000 0.02s user 0.03s system 0% cpu 7.152 total
tail -c +2 7.07s user 0.03s system 99% cpu 7.159 total
shasum -a 256 0.51s user 0.06s system 7% cpu 7.154 total
leijurvs-MacBook-Pro:~ leijurv$ time cat /dev/zero | head -c 100000000 | gtail -c +2 | shasum -a 256
f4be792b71a024a60d77b3ac4c1c2b88ac51480fa25f88d10865827f8c086506 -
cat /dev/zero 0.00s user 0.02s system 4% cpu 0.497 total
head -c 100000000 0.02s user 0.08s system 18% cpu 0.496 total
gtail -c +2 0.05s user 0.10s system 30% cpu 0.496 total
shasum -a 256 0.47s user 0.02s system 99% cpu 0.496 total
leijurvs-MacBook-Pro:~ leijurv$