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))のコードから返された値に基づいてソートするzsh
glob修飾子を使用して、タイムスタンプでファイルリストをソートします。oe
n
$REPLY
[...]
このコードはstrftime -r
(strftime
実際には逆strptime
)を使用して、ファイル名のタイムスタンプを秒単位のエポック時間に変換します。
その後、リストを繰り返して、各5文字プレフィックスの最新のファイルを$latest
連想配列に書き込みます。
${a:|b}
次に、配列減算演算子を使用して、その要素に$all
ない要素$keep
(関連付け配列自体の値を含む$latest
)を削除します。
*.err.*.csv
現在のディレクトリ内のすべてのファイルは、ユーザーが指定した形式と見なされます。ただし、一部の例に示すように、日付要素がs-
ではなく_
sで区切られたファイル名も受け入れることができます(ksh93-convert sをsとして使用-
)_
スタイル${var//pattern/replacement}
演算子)。