find printf와 cksum을 결합해야 합니다.

find printf와 cksum을 결합해야 합니다.

저는 분석을 위해 파일 시스템 데이터를 데이터베이스로 빨아들여야 하는 무서운 상황에 처해 있었습니다. 이 데이터를 추출하는 데 사용하는 방법 중 하나는 다음 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::bashreadmode:uid:gid:size:ctime:./dir/file:modeuidgidsizectime./dir/file:/find

또한 이 -printf술어는 GNU 구현에만 해당되며 find이식 가능하지 않습니다. -z텍스트가 아닌 데이터를 처리하는 기능도 sortGNU의 확장입니다.

관련 정보