Linux - 이름에 특정 패턴이 포함된 여러 파일을 나열하고 삭제합니다.

Linux - 이름에 특정 패턴이 포함된 여러 파일을 나열하고 삭제합니다.

Windows 파일 기록을 사용하여 생성된 파일과 폴더가 포함된 폴더가 여러 개 있습니다. 파일 이름은 모두 동일한 구조를 갖습니다. 예를 들어 -Super secret document (YYYY_MM_DD HH_MM_SS UTC).ext

예를 들어문서폴더는 다음과 같습니다.

...
Default (2020_10_28 06_34_32 UTC).rdp
Default (2020_10_29 06_43_49 UTC).rdp
Default (2020_11_02 06_45_18 UTC).rdp
desktop (2019_10_03 12_32_29 UTC).ini
desktop (2019_11_13 10_57_26 UTC).ini
desktop (2019_12_11 16_12_56 UTC).ini
...
Copy of 2019 (2019_08_03 12_32_29 UTC).xlsx'
Copy of 2019 (2019_10_03 12_32_29 UTC).xlsx'
VW (2020_09_08 12_12_20 UTC).docx
VW (2020_09_08 14_27_50 UTC).docx
Min20071007510 (2020_07_10 05_56_02 UTC).pdf
Min20071007510 (2020_07_11 05_56_02 UTC).pdf
...

이 명령을 사용하면 find지정된 구조로 파일을 필터링할 수 있습니다.

find * -type f -name "*\ (*_*_*\ *_*_*\ UTC).*"

노력하고있어제거하다각 파일의 최신 복사본을 제외한 모든 개별 파일에 대해 이 작업을 수행하는 방법을 모르겠습니다.

감사해요!

답변1

#!/bin/bash

# Get a list of files
files=$(find . name "*.dat" | sort -r)

lastfile=""
IFS=$'\n'
for filename in $files
do
        parts=( $(grep -Eo '.* |\(.*\)' <<< "$filename") )

        # Get the first part of the file name
        filepart="${parts[0]}"

        # If this is a new set of files, this is the file kept.
        if [ "$filepart" != "$lastfile" ]
        then
                echo "Keeping $filename"
        else
                echo "Removing $filename"
                rm $filename
        fi
        lastfile=$filepart
done

여기서는 2단계 프로세스가 사용됩니다.

먼저 모든 파일 목록을 얻습니다. 그것이 find순서입니다. find /path/파일 디렉터리를 선택하려는 경우 파일 세트의 모드를 수정해야 할 수도 있습니다 . 목록은 역순으로 정렬됩니다. 이렇게 하면 가장 최근(최신) 날짜의 패턴이 먼저 표시됩니다.

이제 목록이 있으므로 이를 반복해 보겠습니다. 파일 이름의 첫 번째 부분이 일치하는 한 첫 번째 파일을 유지합니다. grep파일 이름을 이름과 날짜 코드의 두 부분으로 나눕니다. 이름은 공백으로 구분하고 날짜 코드는 대괄호로 구분해야 합니다. 이것은 변수를 형성합니다 parts. 파일의 첫 번째 부분과 마지막 부분을 비교하면 새로운 데이터 세트에 있는지 알 수 있습니다. 기억하세요: 목록은 정렬되어 있으므로 파일 이름의 첫 번째 부분이 변경되는 경우에만 발생합니다.

더 설득력 있는 솔루션이 있을 수 있고 다른 사람들이 의견을 추가할 수도 있습니다. 저는 bash스크립팅 전문가이지만 결코 마스터는 아닙니다.

답변2

ChatGPT의 도움으로 문제를 성공적으로 해결했습니다. (저는 게으릅니다.)

다음 스크립트는 Windows 파일 기록 기반 백업을 반복적으로 수행하고 파일의 최신 복사본을 제외한 모든 복사본을 삭제합니다.

#!/bin/bash

declare -A latest_files

# Find all files in the current directory and its subdirectories
find . -type f -print0 | while IFS= read -r -d '' file; do
    # Check if the file has a date in the format (YYYY_MM_DD HH_mm_ss UTC)
    if [[ $file =~ \(([0-9]{4}_[0-9]{2}_[0-9]{2} [0-9]{2}_[0-9]{2}_[0-9]{2} UTC)\) ]]; then
        date_match="${BASH_REMATCH[1]}"
        # Extract the base filename (excluding the date and extension)
        base_filename="${file%% (*}.${file##*.}"

        # If the date is greater than the stored date for the same full filename or if the filename is not stored
        if [[ "${latest_files[$file]}" < "$date_match" || -z "${latest_files[$file]}" ]]; then
            # Keep the latest version of the file
            latest_files["$file"]="$date_match"

            # Remove the older versions with the same full filename
            for old_file in "${!latest_files[@]}"; do
                if [[ "$old_file" != "$file" && "${old_file%% (*}" == "${file%% (*}" && "${latest_files[$old_file]}" != "$date_match" ]]; then
                    rm -f "$old_file"
                fi
            done
        else
            # Remove this version as it's older
            rm -f "$file"
        fi
    fi
done

답변3

정규식을 사용할 수 있습니다찾다주문하다. 특정 사례의 경우 명령은 다음과 유사합니다. find /path/to/backup/ -type f -regextype posix-extended ! -regex '.*_backup_[0-9]+\.ext' -delete

유용하길 바랍니다!

관련 정보