最新のファイルを選択して名前でグループ化

最新のファイルを選択して名前でグループ化

次の名前構造のファイルを含むディレクトリがあります。

<device>.<yyyy-mm-dd-hh-mm-ss> 

各デバイスに対して、これらの構成バックアップの最後のXコピーを保持するスクリプトを作成しています。これを達成するにはどのような選択魔法が必要ですか?

BASHを考えていますが、実際には言語に拘束されていません。

答え1

ワイルドカード文字はファイル名をアルファベット順に拡張します。日付形式はアルファベット順に一致するため、要件はワイルドカードの最後のX一致(またはXより小さい場合はすべての一致)を維持することに要約されます。バックアップが一致するファイルであるとし、$device.*必要に応じてパターンを調整します。

zshから:

set -- $device.*
if [[ $# -gt $X ]]; then set -- $@{[-$X,-1]}; fi
cp -- $@ /retain/area/

Bourneスタイルのシェル(ash、bash、ksh ...)から:

set -- "$device".*
if [ $# -gt $X ]; then shift $(($#-$X)); fi
cp -- "$@" /retain/area

実際に古いファイルを削除するには、X以外の最初の一致から削除する必要があります(Xより少ない場合は一致しません)。

zshから:

files=($device.*)
rm -f -- $files[1,-$X-1]

他のシェルでは:

set -- "$device".*
while [ $# -gt $X ]; do
  rm -- "$1"
  shift
done

答え2

lsデフォルトでは、語彙順に並べ替えられるファイル名を利用してください。

ls | awk -F . '
    $1 != current_device {
        current_device = $1
        n5[$1] = n4[$1]
        n4[$1] = n3[$1]
        n3[$1] = n2[$1]
        n2[$1] = n1[$1]
        n1[$1] = $0
    }
    END {
        for (device in n1) {
            print n1[device]
            print n2[device]
            print n3[device]
            print n4[device]
            print n5[device]
        }
    }
'

デバイス名にドットが含まれていないとします。結果がソートされない可能性があります。

答え3

ただし、一部の変更が必要な場合があります。

ls <DEVICE>.* | sort -r | tail -n +<X+1> | xargs echo rm 

これにより、rm文が出力され、「echo」が削除され、直接削除されます。

関連情報