古いファイルから削除してディスク使用容量割合を保つシェルスクリプト

2020-07-24

KDE neonを使おう

t f B! P L
 改行のあるファイル名の作成方法とwhile..do..doneループ文での処理-p--qを踏まえて、linuxBean14.04(183)古いファイルから削除してディスク使用容量割合を保つシェルスクリプト-p--qを書き直します。

古い順にソートしたファイルリストを\0区切りで取得する


~/tmpフォルダに改行を含んだファイル名の2つのファイルがあります。


 find ~/tmp -type f -printf "%T@ %p\0" | sort -nz
pq@linuxBean:~$ find ~/tmp -type f -printf "%T@ %p\0" | sort -nz
1595549122.6065589790 /home/pq/tmp/foo
bar1595555858.7341951550 /home/pq/tmp/foo2
bar2pq@linuxBean:~$ 
sortはzオプションで\0(ヌル文字)区切りで出力されます。

%T@(Jan. 1, 1970, 00:00 GMT からの経過秒数)でソートした\0区切りのファイルリストが取得できました。

改行が出力されていないので次のプロンプトが続けて表示されています。

あとは%T@を削ればいいはずです。

find ~/tmp -type f -printf "%T@ %p\0" | sort -nz | sed -z 's/[^ ]* //'
pq@linuxBean:~$ find ~/tmp -type f -printf "%T@ %p\0" | sort -nz | sed -z 's/[^ ]* //'
/home/pq/tmp/foo
bar/home/pq/tmp/foo2
bar2pq@linuxBean:~$ 
sedもzオプションで\0区切りで出力されます。

これで改行文字を含んだファイル名のファイルも一覧に取得できました。

 sedで先頭からスペースまでの文字列を削っています。

 sedで使える正規表現は監視カメラが生成した264ファイルをmp4ファイルに変換する-p--qでみたBREかEREのみになります。

sedでもPRCEが使えたら便利なのに、と思って調べたらPCRE Regex to SED - Stack Overflowを見つけました。

PCREを使いたければsedでなくてpealを使えばいいそうです。

 古いファイルから削除してディスク使用容量割合を保つシェルスクリプト


#!/bin/bash
# dashではdoneへのリダイレクトが使えない。
# 削除対象のファイルがあるディレクトリパス。このディレクトリも空になると削除される。
DIRNAME=public/videos
# ディスク使用容量%。この容量を超えると古いファイルから削除していく。
P=95
# ディスク容量が指定%以上の間、古いファイルから削除していく。
while read -r -d '' F ; do
  if  [ $(df / | tail -1 | sed 's/^.* \([0-9]*\)%.*$/\1/') -gt $P ]; then
    rm "$F"
  else
    break
  fi
done < <(find $DIRNAME -type f -printf "%T@ %p\0" | sort -nz | sed -z 's/[^ ]* //')
# 指定ディレクトリ以下の空ディレクトリを削除。最下層からイテレートされて指定ディレクトリも削除される。
find $DIRNAME -type d -empty -delete
keepspace.shとして保存しました。

これで改行を含むファイル名のファイルがあっても対応できるはずです。

結局効率がよさそうなので変数を2つ使う次の方法を使うことにしました。
#!/bin/bash
# dashではdoneへのリダイレクトが使えない。
# 削除対象のファイルがあるディレクトリパス。このディレクトリも空になると削除される。
DIRNAME=public/videos
# ディスク使用容量%。この容量を超えると古いファイルから削除していく。
P=95
# ディスク容量が指定%以上の間、古いファイルから削除していく。
while read -r -d '' D F ; do
  if  [ $(df / | tail -1 | sed 's/^.* \([0-9]*\)%.*$/\1/') -gt $P ]; then
    rm "$F"
  else
    break
  fi
done < <(find $DIRNAME -type f -printf "%T@ %p\0" | sort -nz)
# 指定ディレクトリ以下の空ディレクトリを削除。最下層からイテレートされて指定ディレクトリも削除される。
find $DIRNAME -type d -empty -delete

日付順のファイルリストをwhile do done文で表示するパターンいろいろ

sedを使う


#!/bin/bash
C=0
while read -r -d '' F
do
  echo line$((++C)): "${F}"
done < <(find ~/tmp -type f -printf "%T@ %p\0" | sort -nz | sed -z 's/[^ ]* //')

変数を2つ使う


#!/bin/bash
C=0
while read -r -d '' D F
do
  echo line$((++C)): "${F}"
done < <(find ~/tmp -type f -printf "%T@ %p\0" | sort -nz)
 Dに経過秒数が入り、Fにファイルパスが入っています。

grepを使う


#!/bin/bash
C=0
while read -r -d '' F
do
  echo line$((++C)): "${F}"
done < <(find ~/tmp -type f -printf "%T@ %p\0" | sort -nz | grep -zo ' .*')
grepしたあと行頭にスペースが残りますが、IFSと判断されてFに代入されるときは先頭のスペースが消えてくれます。

ただしこの方法が使えるのはgrepのバージョンが2.25以上のときのみです。

それ以前のバージョンではzoオプションを付けても\0区切りで出力されず、改行で出力されてしまいます(bash - How to make grep separate output by NULL characters? - Stack Overflow)。

KDE neonではgrep v3.1なので問題ありませんが、linuxBean14.04ではv2.16なのでバージョンアップしないといけません。

 しかし、Grep - GNU Project - Free Software FoundationIndex of /gnu/grepからgrep-3.4.tar.xzをダウンロードして、ビルドはできましたが、どうやっても-Pオプションを有効にしてビルドする方法がわかりませんでした。

ブログ検索 by Blogger

Translate

最近のコメント

Created by Calendar Gadget

QooQ