Bash 문자열 작업 속도 및 파이프

Bash 문자열 작업 속도 및 파이프

md5 체크섬과 파일 이름으로 가득 찬 파일이 있습니다. 각 행에 대해 일부 처리를 수행해야 하므로 다음 사항을 알아야 합니다.

  • 체크섬은 무엇입니까
  • 파일 이름은 무엇입니까

그리고 적절한 조치를 취하세요. 즉, 체크섬을 변수에 넣은 다음 파일 이름을 넣어야 합니다. 파일 이름에 ASCII가 아닌 문자가 포함될 수 있지만 개행 문자를 표시하고 싶지 않습니다. 다음과 같습니다.

05c00367e8914ca1be0964821d127977  ./.fseventsd/0000000000097aa1
cd9d4291f59a43c0e3d73ff60a337bb5  ./.fseventsd/00000000000fdfec
5d1280769e741e04622cfd852f33a138  ./.fseventsd/0000000000103197
8dda3534e5bbc0be1d15db2809123c50  ./.fseventsd/000000000017c9ca
(...etc., about 100,000 lines)

전통적으로 다음과 같이 할 수 있습니다.

md5sum=$(echo $line | awk '{print $1}')
filename=$(echo $line | sed 's/[^ ]*  //')

하지만 이렇게 하면 얼마나 더 빨라질까요?

md5sum=${line%%" "*}
filename=${line#*"  "}

답변1

예, bash 내부 명령을 사용하면 많은 시스템 호출을 피할 수 있습니다. 특히 재귀가 있는 경우에는 더욱 그렇습니다.

또 다른 예: $(ls)에 대해 *를 사용해야 합니다.

Bash는 문자열에 대한 간단한 작업(잘라내기 및 바꾸기)을 수행하기 위한 몇 가지 방법을 제공합니다. 하지만 그게 다야. 왜냐하면 그것은 그것을 위해 설계되지 않았기 때문입니다. 예: 외부 명령 없이 문자열에 패턴이 있는지 확인하는 것은 어렵습니다.

외부 프로그램이 해당 작업에 더 잘 최적화되었습니다(cat, sed, grep, awk, cut, sort...).

답변2

변수 중 하나를 설정하여 테스트했습니다. 이 스크립트를 두 번 실행합니다.

while read line; do
        md5sum=${line%%" "*}
        #md5sum=$(echo $line | awk '{print $1}')
        echo "SUM: $md5sum FILE:_$file"
done < manifest.Stuph.180620

먼저

md5sum=${line%%" "*}

다음은

md5sum=$(echo $line | awk '{print $1}')

"manifest.Stuph.180620" 파일의 길이는 100939줄(==약 14MiB)이며, 결과는 다음과 같습니다.

첫 번째 실행(bash의 내장 문자열 조작 사용)

real    0m4.750s
user    0m4.174s
sys     0m0.550s

두 번째 실행(파이프 사용)

real    10m54.255s
user    4m42.257s
sys     7m32.880s

나 같은 일부 사람들은 속도가 중요하다면 어쨌든 셸에서 장난을 치면 안 된다고 말할 것입니다. 그러나 때로는 작업을 완료하기 위해 어떤 환경을 사용하든 관계없이 더 효율적이기를 원할 수도 있습니다.

이렇게 하면 다음 사항에 유의하세요.

while read md5sum filename; do
    (...etc...)

변수 할당을 수행하는 것보다 훨씬 효율적이지만 명령 대체/파이핑/awk 구성을 제거하는 지점은 아닙니다. 제가 가장 흥미로운 점은 bash 내장 성능과 외부 명령 사용의 차이입니다. 아름다운 내장 기능을 더욱 열심히 배우고 활용하겠습니다!

관련 정보