참고: jeff-schaller의 답변이 있지만 zsh
; 그래서 나는 을 기반으로 답변을 얻고 싶습니다 Bash
.
나는 백업 디렉터리에서 오래된 파일을 조건부로 삭제하는 Bash 스크립트를 만드는 것을 좋아합니다.
2개의 개별 파일 백업에는 2가지 조건이 있습니다.
1, 의 최신 복사본을 유지 Edge_Profile_*.tgz
하고 나머지는 삭제합니다.Edge_Profile_*.tgz
5일이 넘은 경우에만.
2, 의 최신 복사본을 유지 Firefox_Profile_*.tgz
하고 나머지는 삭제합니다 Firefox_Profile_*.tgz
.그 사람들이 몇 살인지는 상관없어.
이 AskUbuntu 답변을 수정하는 방법은 다음과 같습니다.https://askubuntu.com/a/933098/928088
스크립트:
#!/bin/bash
LOG_FILE="/home/admn/Cleanup.log"
TEMP_LOG="/tmp/Temp_Cleanup.log"
mv $LOG_FILE $TEMP_LOG
{
cd /home/admn/Downloads/Test;
echo "Cleanup log:" `date`
find /home/admn/Downloads/Test/Edge_Profile_*.tgz -type f \( -mtime +5 -printf 'Y\t' -o -printf 'N\t' \) -printf '%A@\t%p\0' |
sort -zk2,2 | head -zn -1 | while read -r -d '' flag _ file; do \
case "$flag" in
'Y') echo rm "$file"
;;
*) echo "skipping $file (too new)"
;;
esac;
done
echo
find /home/admn/Downloads/Test/Firefox_Profile_*.tgz -type f \( -printf 'Y\t' -o -printf 'N\t' \) -printf '%A@\t%p\0' |
sort -zk2,2 | head -zn -1 | while read -r -d '' flag _ file; do \
case "$flag" in
'Y') echo rm "$file"
;;
*) echo "skipping $file (too new)"
;;
esac
done
} &>> $LOG_FILE
cat $TEMP_LOG >>$LOG_FILE
exit;
다음을 사용하여 로그 파일에 출력합니다 echo
.
/usr/local/scripts/cleanup.sh
rm /home/admn/Downloads/Test/Edge_Profile_Jul_06_2021_00-35.tgz
rm /home/admn/Downloads/Test/Edge_Profile_Jul_07_2021_00-35.tgz
....
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_12_2021_00-35.tgz (too new)
skipping /home/admn/Downloads/Test/Edge_Profile_Jul_13_2021_00-35.tgz (too new)
....
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_01_2021_00-35.tgz
rm /home/admn/Downloads/Test/Firefox_Profile_Jul_02_2021_00-35.tgz
....
다음 을 제외하고 실제로 스크립트를 실행하는 동안 로그 파일에 출력됩니다 echo
.
/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_12_2021_00-35.tgz (too new): No such file or directory
/home/admn/Downloads/cleanup.sh: line 24: skipping /home/admn/Downloads/Test/Edge_Profile_Jul_13_2021_00-35.tgz (too new): No such file or directory
....
디렉터리의 총 파일: 20개 파일
1, Edge_Profile_*.tgz: 7월 6일부터 7월 17일까지: 12개 파일
2, Firefox_Profile_*.tgz: 7월 1일부터 7월 8일까지: 8개 파일
문제:
(1) 나생각하다스크립트는 작동하고 있지만 무슨 일이 일어나고 있는지 알지 못한 채 대부분의 부분을 수정했기 때문에 잘 모르겠습니다.
(2) 로그 파일로 출력:
echo
다음과 같이 파일 이름(전체 경로가 아님)만 제외하고 로 얻은 로그 파일에서 정확히 동일한 출력을 선호합니다.
rm Edge_Profile_Jul_11_2021_00-35.tgz
skipping Edge_Profile_Jul_12_2021_00-35.tgz (too new)
운영 체제: 우분투 MATE 21.04
정말 감사합니다.
답변1
파일에 직접 액세스할 수 있는 셸에서는 수정 시간을 기준으로 파일을 조작하는 것이 훨씬 쉽습니다. zsh는 그러한 쉘 중 하나입니다. 간단히 sudo apt install zsh
설치하면 됩니다. 파일이 하나의 디렉터리에 있는 것으로 나타나므로 이 답변은 비재귀적입니다. 더 간단한 사례를 먼저 시연해 보겠습니다.
Firefox_Profile_*.tgz의 최신 복사본을 유지하고 오래된 파일의 나머지 부분을 삭제하려면:
echo would rm -v -- Firefox_Profile_*.tgz(.om[2,-1])
제거
echo would
올바른 것처럼 보이면 해당 부분을 . 이것은glob(와일드카드) 한정자괄호 안에는 세 가지 작업을 수행합니다.- 일반 파일(디렉토리나 소켓 등이 아닌)만 선택합니다.
.
- 수정 시간을 기준으로 최신순으로 파일을 정렬(정렬)합니다.
om
- 두 번째 요소부터 끝까지 결과 목록의 조각을 선택합니다. 첫 번째(최신) 파일을 건너뜁니다.
[2,-1]
일치하는 파일이 없으면 zsh는 중지하고 "zsh: 일치하는 항목을 찾을 수 없습니다"라는 메시지를 표시하며
rm
.- 일반 파일(디렉토리나 소켓 등이 아닌)만 선택합니다.
Edge_Profile_*.tgz의 최신 복사본을 유지하고 5일이 지난 경우에만 나머지 복사본을 삭제하려면 먼저 최신 복사본을 가져옵니다.
newest=(Edge_Profile_*.tgz(.om[1]))
... 그런 다음 5일보다 오래된 항목을 얻습니다.
older=(Edge_Profile_*.tgz(.m+5))
여기서 새로운 부분은 수정자
+5
에 있습니다m
. 그러면 5일보다 오래된 파일이 선택됩니다. 그런 다음 제거할 목록에 최신 항목이 없는지 확인합니다.remove=("${(@)older:|newest}")
여기서 새로운 부분은 배열 빼기 기호입니다
:|
. 그것은에 문서화되어 있습니다zsh 매뉴얼의 매개변수 확장 섹션. "최신"이 아닌 "이전" 요소를 선택합니다. 마지막으로 해당 파일 목록을 제거합니다.echo would rm -v -- "${remove[@]}"