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는 parallel
CPU 코어 수에 따라 동시 작업 수를 제한합니다. 요즘에는 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를 사용하면 다음과 같은 작업을 수행할 수 있습니다.-d
xargs
parallel
xargs
shuf -n 3 list_of_files.txt | xargs -d '\n' cksum
GNU를 사용할 수 있다면 xargs
( 으로 하루를 절약하기 위해 -d '\n'
) 아마도 GNU를 사용할 수 있을 것입니다 parallel
. -j 1
GNU를 사용할 때 잊어버리면 parallel
명령의 성능이 저하될 수 있지만 여전히 작동합니다. -d '\n'
GNU를 사용할 때 잊어버렸고 xargs
경로 이름이 있는 그대로 제공된다면 이는 버그입니다. 그래서 제가 parallel
먼저 GNU를 추천했습니다.
GNU 병렬은 널 종료 문자열(옵션은 -0
)을 처리할 수 있으며 GNU xargs
( -0
대신 -d '\n'
) 및 GNU shuf
( with -z
)도 마찬가지입니다. 입력 파일은 개행 문자로 끝나는 줄을 사용하지만 개행 문자가 포함될 수 있는 경로 이름으로 작업해야 하는 경우 파일의 종결자를 변경하고 적절한 옵션을 추가하는 것이 좋습니다.