이름이 파일에 나열되어 있는 파일을 무작위로 선택하여 체크섬을 계산합니다.

이름이 파일에 나열되어 있는 파일을 무작위로 선택하여 체크섬을 계산합니다.

list_of_files.txt각 줄이 디스크의 파일에 해당하는 이름의 파일이 있다고 가정해 보겠습니다 . 예를 들어:

dir1/fileA.ext1
dir1/subdir1/fileB.ext2
fileC.ext3
dir2/fileD.ext4
fileE.ext5

해당 목록에서 여러 파일을 무작위로 선택하여 계산하고 cksum싶습니다 md5sum.

를 사용하여 3개의 파일을 무작위로 선택할 수 있다는 것을 알고 있지만 해당 파일을 텍스트 콘텐츠 대신 파일 이름으로 처리하려면 shuf -n 3 list_of_files.txt어떻게 해야 합니까 ?cksum

답변1

파일의 경로가 줄바꿈으로 끝나고 있는 그대로 제공되는 경우, 즉 각 줄이 별도의 축어적 경로인 경우 쉘 루프가 수행됩니다.

shuf -n 3 list_of_files.txt | while IFS= read -r pth; do
   cksum "$pth"
done

또한 있습니다 xargs(참조POSIX 사양그리고 더 발전된암소 비슷한 일종의 영양xargs), 있다암소 비슷한 일종의 영양parallel(메모GNU가 아닌 parallel존재그리고 나는 그것을 언급하는 것이 아닙니다). 올바른 도구와 적절한 옵션을 사용하면 하나의 cksum프로세스를 두 개 이상의 경로로 만들거나( cksum일반적으로 더 적은 프로세스를 생성하는 것이 유익함) 두 개 이상의 cksum프로세스를 병렬로 실행할 수 있습니다.

3개 정도의 파일만 처리하려면 이식성 때문에 쉘 루프를 고수할 수 있습니다. 파일이 크고 병렬로 실행되는 세 개의 프로세스가 한 번에 cksum하나씩 실행되는 것보다 훨씬 더 빠를 것으로 기대하지 않는 한. cksum저는 GNU 전문가는 아니지만 parallel해결책은 다음과 같이 간단해 보입니다.

 shuf -n 3 list_of_files.txt | parallel cksum

기본적으로 GNU는 parallelCPU 코어 수에 따라 동시 작업 수를 제한합니다. 요즘에는 3개 이상의 코어가 일반적이므로 명령은 아마도 3개의 cksum프로세스를 병렬로 실행할 것입니다. 공식적으로 이것은 이식성이 없습니다. 또한 세 개의 파일을 병렬로 처리한다는 것은 세 개의 파일을 병렬로 읽는다는 것을 의미합니다. I/O는 병목 현상을 일으킬 수 있으며 이는 병렬 작업의 이점을 감소시키거나 상황을 더욱 악화시킬 수도 있습니다.

그래도 parallel유용할 수 있습니다. -j 1작업 수를 1로 제한하는 데 사용합니다 .

 shuf -n 3 list_of_files.txt | parallel -j 1 cksum

파일은 쉘 루프처럼 순차적으로 처리되지만 구문은 더 간단합니다. 쉘 루프의 경우 원하는 것을 알아야 합니다.IFS= read -r pth, 뿐만 아니라 read pth; 그리고 당신은 (많은 껍질에서) 당신이 원하는 것을 알아야합니다cksum "$pth", 아니다 cksum $pth. GNU를 사용한 솔루션은 parallel오류가 덜 발생합니다.키스.

Note는 xargs기본적으로 따옴표와 백슬래시를 해석하고 공백을 구분 기호로 간주합니다. 이는 shuf -n 3 list_of_files.txt | xargs cksum아마도 당신이 원하는 것이 아닐 수도 있음을 의미합니다. 귀하의 예는 작동하지만 일반적으로 파일에 추가 따옴표 및/또는 백슬래시가 필요합니다. x또는 GNU의 이식 불가능한 옵션이 xargs -d '\n'어디에 있는지 필요합니다 . 내 가정은 "파일의 경로가 개행 문자로 끝나고 있는 그대로 제공됩니다"였습니다. 이러한 가정 하에 GNU는 기본적으로 작동하지만(즉, 추가 옵션 없이) xargs는 작동하지 않습니다. GNU를 사용하면 다음과 같은 작업을 수행할 수 있습니다.-dxargsparallelxargs

shuf -n 3 list_of_files.txt | xargs -d '\n' cksum

GNU를 사용할 수 있다면 xargs( 으로 하루를 절약하기 위해 -d '\n') 아마도 GNU를 사용할 수 있을 것입니다 parallel. -j 1GNU를 사용할 때 잊어버리면 parallel명령의 성능이 저하될 수 있지만 여전히 작동합니다. -d '\n'GNU를 사용할 때 잊어버렸고 xargs경로 이름이 있는 그대로 제공된다면 이는 버그입니다. 그래서 제가 parallel먼저 GNU를 추천했습니다.

GNU 병렬은 널 종료 문자열(옵션은 -0)을 처리할 수 있으며 GNU xargs( -0대신 -d '\n') ​​및 GNU shuf( with -z)도 마찬가지입니다. 입력 파일은 개행 문자로 끝나는 줄을 사용하지만 개행 문자가 포함될 수 있는 경로 이름으로 작업해야 하는 경우 파일의 종결자를 변경하고 적절한 옵션을 추가하는 것이 좋습니다.

관련 정보