찾기 모드: 오래된 파일 정렬 및 삭제

찾기 모드: 오래된 파일 정렬 및 삭제

aa_te, bb_co, cc_co, dd_xy파일 이름의 처음 5자( )와 날짜 및 시간을 기준으로 각 파일 패턴에서 오래된 파일을 삭제하고 최신 파일만 유지하고 싶습니다.

노트:

모든 파일이 .err.mm_dd_yyyy hr_mm_ss am/pm.csv정렬됩니다. 파일 이름 길이는 다를 수 있습니다.

예: 내 폴더에 다음 CSV 파일이 있습니다.c/test

aa_te_bbc_207_mc_ghghgh.err.05_31_2021 7_15_04 am.csv
aa_te_ccd.err.05_30_2021 7_55_35 pm.csv
bb_co_ddee_354_m.err.06_15_2021 5_20_00 am.csv
bb_co_eeffff.err.06_15_2021 5_20_01 am.csv
cc_co_eeffyy_cc.err.04_10-2020 12_00_00 am.csv
dd_xy_eeffyyvv_cc.err.04_10-2020 12_00_00 am.csv
dd_xy_eeffyyvv_cc.err.04_10-2020 12_10_25 am.csv

미래에 대한 나의 기대는 여전히 이렇습니다.

aa_te_bbc_207_mc_ghghgh.err.05_31_2021 7_15_04 am.csv
bb_co_eeffff.err.06_15_2021 5_20_01 am.csv
cc_co_eeffyy_cc.err.04_10-2020 12_00_00 am.csv
dd_xy_eeffyyvv_cc.err.04_10-2020 12_10_25 am.csv

답변1

rm가능하다면 마지막 줄에서 "echo"를 제거하세요.

#!/bin/bash

# search dir
dir=./

# function conv PATTERN
conv() {
  # extract date from file name: 06_15_2021 5_20_00 am
  date=${1%.*}
  date=${date##*.}

  # sanitize date string: 06/15/2021 5:20:00-am
  date=${date//[^0-9AaPpMm]/-}
  date=${date/-//}
  date=${date/-//}
  date=${date/-/ }
  date=${date/-/:}
  date=${date/-/:}

  # print epoch time
  date --date="$date" +%s || return 1
  return 0
}

# search: *m.csv
for file in "$dir"*[Mm].[Cc][Ss][Vv]
  do
    [ -f "$file" ] || continue
    # file name: bb_co_ddee_354_m.err.06_15_2021 5_20_00 am.csv
    file=${file##*/}
    # base name: bb_co_ddee_354_m
    name=${file%%.*}
    # suffix: ddee_354_m
    del=${name#*_}
    del=${del#*_}
    # short name = base name - _suffix: bb_co
    name=${name%_$del}
    # convert date
    date=$(conv "$file") || continue

    # search short name: bb_co_*m.csv
    for search in "${dir}${name}"_*[Mm].[Cc][Ss][Vv]
      do
        # delete older file
        date2=$(conv "${search##*/}") || continue
        [ "$date" -gt "$date2" ] && echo rm "$search"
    done
done

답변2

zsh대신 을 사용하면 bash다음을 수행할 수 있습니다.

#! /bin/zsh -

zmodload zsh/datetime
typeset -A latest=()
all=(
  *.err.*.csv(Nnoe['LC_ALL=C strftime -rs REPLY %m_%d_%Y_%I_%M_%S_%p ${${${REPLY:r}##*.err.}//[- ]/_}'])
)
for file in $all; do
  latest[$file[1,5]]=$file
done

keep=($latest)
echo rm -f -- ${all:|keep}

(파일이 있는 디렉터리에서 실행하고 echo괜찮아 보이면 삭제하세요(드라이런의 경우))

$all(numeric(using))의 코드에서 반환된 값을 기준으로 정렬하는 zshglob 한정자를 사용하여 타임스탬프별로 파일 목록을 정렬합니다 .oen$REPLY[...]

이 코드는 strftime -r( strftime실제로는 반대 strptime)를 사용하여 파일 이름의 타임스탬프를 초 단위의 에포크 시간으로 변환합니다.

그런 다음 목록을 반복하여 각 5자 접두사에 대한 최신 파일을 $latest연관 배열에 기록합니다.

${a:|b}그런 다음 배열 빼기 연산자를 사용하여 $all해당 요소에 없는 요소 $keep(연관 배열 자체의 값을 포함함 $latest)를 제거합니다.

*.err.*.csv현재 디렉토리의 모든 파일은 사용자가 지정한 형식으로 간주 됩니다. 그러나 일부 예에서 표시된 것처럼 날짜 요소가 s -대신 _s로 구분되는 파일 이름도 수용할 수 있습니다(ksh93-convert s를 s로 사용 -) _스타일 ${var//pattern/replacement}연산자 ).

관련 정보