저는 분석을 위해 파일 시스템 데이터를 데이터베이스로 빨아들여야 하는 무서운 상황에 처해 있었습니다. 이 데이터를 추출하는 데 사용하는 방법 중 하나는 다음 GNU find 명령줄을 사용하는 것입니다.
find . -printf '__:__%M__:__%u__:__%g__:__%s__:__%Cs__:__%p\n'
이는 __:__
이론적으로 실제 파일이나 디렉터리 이름에 나타나지 않는 구분 기호 역할을 합니다.
문제는 파일의 빠른 체크섬이 필요하기 때문에 이제 cksum도 병합해야 한다는 것입니다.
난 무엇인가?생각하다당신이 해야 할 일은 다음과 같은 일을 하는 것뿐입니다:
find . -exec cksum {} \; -printf '__:__%M__:__%u__:__%g__:__%s__:__%Cs__:__%p\n'
이로 인해 이 모든 것이 파일 시스템을 통한 한 줄 및 한 단계 프로세스가 됩니다. 그러나 이것은 별도의 줄에 cksum을 인쇄합니다.
printf에서 사용할 수 있는 값으로 표시되도록 -exec cksum을 결합하는 방법이 있습니까?
이를 수행하는 데 가장 적합한 도구를 찾으십니까? 다른 도구를 사용해야 합니까?
감사합니다!
답변1
먼저 몇 가지 참고 사항:
__:__
__:__
파일 경로 나 경로 앞에 인쇄된 필드에는 차단 문자나 개행 문자가 나타나지 않습니다 .mkdir -p $'__:__/\n\n\n'
확인해보고 싶다면 시도해 보세요.0을 제외한 모든 바이트 값이 파일 경로에 나타날 수 있습니다. 바이트는 문자를 형성할 필요도 없으므로 파일 경로는 일반적으로 한 줄의 텍스트는 물론 텍스트로 간주될 수 없습니다. 일반적으로 파일 경로 목록을 안정적으로 표현하기 위해 NUL로 구분된 레코드를 사용합니다.
%u
그리고%g
당신에게ㅏ파일의 uid/gid에 해당하는 사용자/그룹 이름입니다. 사용자 ID는 여러 사용자 이름을 가질 수 있으며, uid 123의 사용자 이름은 오늘의 사용자 이름일 수도 있고 내일의 사용자 이름일 수도 있습니다. 즉, 얻는 내용은 파일 고유의 정보가 아니라 시스템의 사용자 데이터베이스에 포함된 정보입니다.보고되는 파일의 순서는
find
정의되지 않습니다. 디렉터리 계층 구조의 내용이 변경된 시기를 감지할 수 있도록 하는 것이 목표라면 목록을 정렬해야 합니다.%Cs
이는 초 단위까지만 정확도를 제공한다는 점에 유의하세요 .%C@
완전한 정확성을 위해 .
여기에서 ( zsh
또는 사용 bash
) 할 수 있습니다.
find . -printf '%M/%U/%G/%s/%C@/%p\0' | LC_ALL=C sort -z |
while IFS=/ read -rd '' mode uid gid size ctime file; do
cksum=$(cksum < "$file") || continue
# do what to have to do with $mode $uid $gid $size $ctime $cksum $file
done
. 보다 더 안정적인 체크섬 알고리즘을 선택할 수도 있습니다 cksum
.
를 사용할 때는 위의 구분 기호 이외의 다른 구분 기호를 bash
선택할 수 없습니다 . /
예를 들어 를 선택했는데 ( 후행 ) 이라는 파일이 :
있으면 , , , 로 분할 되어 후행이 손실됩니다. 이는 POSIX 요구 사항입니다(zsh에서는 무시됨). 출력 파일 경로의 끝에 나타나지 않도록 보장됩니다 ../dir/file:
:
bash
read
mode:uid:gid:size:ctime:./dir/file:
mode
uid
gid
size
ctime
./dir/file
:
/
find
또한 이 -printf
술어는 GNU 구현에만 해당되며 find
이식 가능하지 않습니다. -z
텍스트가 아닌 데이터를 처리하는 기능도 sort
GNU의 확장입니다.