find 및 exec를 사용하여 스크립트 성능 향상 [닫기]

find 및 exec를 사용하여 스크립트 성능 향상 [닫기]

주어진 디렉토리를 통과하고 30일 이내에 사용된 파일이 하나도 포함되지 않은 파일을 자동으로 압축하는 스크립트가 있습니다. 이제 exec와 함께 find를 사용하여 성능을 향상시킬 수 있는지 궁금합니다. 몇 가지를 시도했지만 작동하지 않습니다. 추천 메뉴가 무엇인가요?

#!/bin/bash
# find all the directories
dirs=`find . -type d`
# iterate every file in every directory
for dir in $dirs
do
        n="totar"
        # search all the file in the directory
        files=`find $dir -type f -atime -30`
        for file in $files
        do
                n="keepasis"
        done
        if [ $n == "totar" ]; then
                tar -zcvf $dir.tgz $dir
                rm -r $dir
        fi
done

내 생각은 두 번째 for 루프를 다음으로 바꾸는 것입니다.

find $dir -type f -atime -30 -exec n="keepasis" {} \;

답변1

find작업에서 변수를 설정하면 -exec해당 변수가 표시되지 않습니다.

파일이 발견되고 그 이름이 인쇄된다는 사실만으로도 find해당 디렉토리를 보관하지 않을 것이라고 결정하기에 충분합니다. 따라서 loop할 필요는 없지만 비어 for file in $files있지 않은지 확인하십시오 $files.

find명령이 이 작업을 지원하는 경우 -quit이를 사용하여 첫 번째 일치 후 중지할 수 있습니다. (바라보다첫 번째 일치 후 find 명령을 어떻게 중지할 수 있나요?)

첫 번째 출력의 출력을 변수에 넣고 토큰화와 함께 for 루프를 사용하는 대신 Lime의 출력을 한 줄씩 find읽는 것이 더 좋습니다 .find

#!/bin/bash
# find all the directories
# -mindepth 1 prevents "find" from printing "."
find . -mindepth 1 -type d | while read -r dir
do
    # a subdirectory might no longer exist if a parent has been archived before
    if [ -d "$dir" ]
    then
        # search any new file in the directory
        newfilefound=`find $dir -type f -atime -30 -print -quit`

        if [ -z "$newfilefound" ]
        then
            tar -zcvf $dir.tgz $dir
            rm -r $dir
        fi
   fi
done

findBash를 사용하는 경우 특수 문자가 포함된 더 많은 디렉토리 이름을 올바르게 처리하도록 첫 번째 것을 개선할 수 있습니다 find . -type d -print0 | while IFS= read -r -d '' dir; do.

여전히 성능 문제가 있습니다.

디렉터리의 하위 디렉터리 어딘가에 새 파일이 포함된 경우 해당 파일을 삭제하지 마세요. 나중에 이 파일이 포함된 모든 하위 디렉터리의 이름을 얻게 됩니다. 이 경우에는 find동일한 새 파일을 찾기 위해 여러 번 사용하게 됩니다.

내 마음에 떠오르는 유일한 해결책은 두 가지 find, 일부 후처리 및 한 가지를 사용하는 것입니다 fgrep.

  1. 모든 새 파일의 이름을 인쇄 하고 find, 파일 이름을 제거하여 출력을 처리하고, 모든 상위 디렉터리를 별도의 줄로 인쇄하고, 중복 항목을 제거하고 목록을 NEWDIRS 파일에 넣습니다.
  2. 두 번째는 find모든 디렉터리 이름을 두 번째 파일 ALLDIRS에 인쇄합니다.
  3. fgrepNEWDIRS의 행과 일치하지 않는 ALLDIRS의 모든 행을 찾는 데 사용됩니다 .

tar디렉터리를 삭제하기 전에 명령이 성공했는지 확인해야 합니다.

관련 정보