주어진 디렉토리를 통과하고 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
find
Bash를 사용하는 경우 특수 문자가 포함된 더 많은 디렉토리 이름을 올바르게 처리하도록 첫 번째 것을 개선할 수 있습니다 find . -type d -print0 | while IFS= read -r -d '' dir; do
.
여전히 성능 문제가 있습니다.
디렉터리의 하위 디렉터리 어딘가에 새 파일이 포함된 경우 해당 파일을 삭제하지 마세요. 나중에 이 파일이 포함된 모든 하위 디렉터리의 이름을 얻게 됩니다. 이 경우에는 find
동일한 새 파일을 찾기 위해 여러 번 사용하게 됩니다.
내 마음에 떠오르는 유일한 해결책은 두 가지 find
, 일부 후처리 및 한 가지를 사용하는 것입니다 fgrep
.
- 모든 새 파일의 이름을 인쇄 하고
find
, 파일 이름을 제거하여 출력을 처리하고, 모든 상위 디렉터리를 별도의 줄로 인쇄하고, 중복 항목을 제거하고 목록을 NEWDIRS 파일에 넣습니다. - 두 번째는
find
모든 디렉터리 이름을 두 번째 파일 ALLDIRS에 인쇄합니다. fgrep
NEWDIRS의 행과 일치하지 않는 ALLDIRS의 모든 행을 찾는 데 사용됩니다 .
tar
디렉터리를 삭제하기 전에 명령이 성공했는지 확인해야 합니다.