私は次のパスを持っています:
/dir1/dir2/
このパスには、さまざまな(関連していない)アプリケーションDetriusを含む次のディレクトリがあります。
follower1234 1-Dec-2018
follower3456 2-Dec-2018
follower4567 3-Dec-2018
follower7890 9-Jan-2019
follower8901 10-Jan-2019
leader8765 4-Dec-2018
bystander6789 5-Dec-2018
今日が2019年1月10日であるとします。
followerXXXX
、leaderXXXX
およびディレクトリがいくらでも存在できるとしますbystanderXXXX
。
私が望むのは、2週間を超えるfollowerXXXX
最新のディレクトリを除くすべてのディレクトリを削除することです。followerXXX
これで、すべてのディレクトリを削除できます。特定の日付以前。しかし、それは私の問題ではありません。 2つの追加パラメータを追加します。
この場合、以下を削除したいと思います。
follower1234 1-Dec-2018
follower3456 2-Dec-2018
follower4567 3-Dec-2018
しかし、
follower7890 9-Jan-2019
follower8901 10-Jan-2019
leader8765 4-Dec-2018
bystander6789 5-Dec-2018
つまり、ファイルを削除したいのです。
(a) 一致パターン
(b) 2週間以上
(c)はパターンに一致する最新のディレクトリではありません(つまり、最後のディレクトリを維持してください)。
私の質問は次のとおりです1つのディレクトリから2週間を超えるすべてのディレクトリを削除するにはどうすればよいですか(ファイルパターンに一致する最新のディレクトリを除く)。
ベストアンサー1
紹介する
質問が修正されました。
私の最初の選択肢(oneliner)は新しい仕様と一致しませんでしたが、十分に古い(14日以上)ディレクトリから最新のディレクトリを保存しました。
私は2番目の選択肢(シェルスクリプト)を作成しました。
@ 1970年1月1日00:00 GMT以降の秒数(小数部を含む)。
seclim
ソートされたディレクトリのリストから「秒制限」のタイムスタンプを取得するには、14日に対応する秒数を減算します。
1. 断線
以前の答えはきれいできれいですが、最新のディレクトリを維持しませんfollower
。次のコマンドラインはこれを行います(スペースを含む名前を管理しますが、改行を持つ名前には問題が発生します)。
find . -type d -name "follower*" -printf "%T+ %p\n"|sort|head -n -1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' | xargs echo rm -r
このディレクトリ構造をテストするには
$ find -printf "%T+ %p\n"|sort
2019-01-10+13:11:40.6279621810 ./follower1
2019-01-10+13:11:40.6279621810 ./follower1/2/3
2019-01-10+13:11:40.6279621810 ./follower1/2/dirnam with spaces
2019-01-10+13:11:40.6279621810 ./follower1/2/name with spaces
2019-01-10+13:11:56.5968732640 ./follower1/2/file
2019-01-10+13:13:18.3975675510 ./follower2
2019-01-10+13:13:19.4016254340 ./follower3
2019-01-10+13:13:20.4056833250 ./follower4
2019-01-10+13:13:21.4097412230 ./follower5
2019-01-10+13:13:22.4137991260 ./follower6
2019-01-10+13:13:23.4138568040 ./follower7
2019-01-10+13:13:24.4219149500 ./follower8
2019-01-10+13:13:25.4259728780 ./follower9
2019-01-10+13:15:34.4094596830 ./leader1
2019-01-10+13:15:36.8336011960 .
2019-01-10+13:15:36.8336011960 ./leader2
2019-01-10+13:25:03.0751878450 ./follower1/2
このように、
$ find . -type d -name "follower*" -printf "%T+ %p\n"|sort|head -n -1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' | xargs echo rm -r
rm -r ./follower1 ./follower2 ./follower3 ./follower4 ./follower5 ./follower6 ./follower7 ./follower8
したがって、最新のディレクトリ(名前が起動しない(そしてゲームにないディレクトリ))follower9
なので除外されます。follower
follower
leader1
leader2
2
次に、タイムスタンダードを追加し、正しく機能して-mtime +14
いることを確認するために別の「テスト実行」を実行します。follower
物理ディレクトリが存在する場所にディレクトリを変更すると、
find . -type d -name "follower*" -mtime +14 -printf "%T+ %p\n"|sort|head -n -1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' | xargs echo rm -r
echo
最後に、私たちはあなたがしたいことをするコマンドラインを削除して持っていました。
find . -type d -name "follower*" -mtime +14 -printf "%T+ %p\n"|sort|head -n -1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' | xargs rm -r
find
follower
名前がで始まり、14日前から変更されていない現在のディレクトリのディレクトリ。- 印刷して分類した後
head -n -1
最新のfollower
ディレクトリを除外。 - タイムスタンプを削除し、各ディレクトリ名の先頭と末尾に二重引用符を追加します。
- 最後に削除したいディレクトリを削除するために、結果
xargs
はパイプを介してパラメータに渡されます。rm -r
2. シェルスクリプト
私は2番目の選択肢(シェルスクリプト)を作成しました。
@ seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
また、2つのオプションがあります。
-n
試運転-v
言葉が多いOPの要求に応じてシェルスクリプトを修正しました。モードを引数として入力「follower*」のような一重引用符内。
prune-dirs
今より一般的なので、シェルスクリプト名を使用することをお勧めします(もはやディレクトリのクリーンアップprune-followers
にのみ使用されるわけではありませんfollower*
)。
実行する操作を「確認」するには、最初にこれら2つのオプションを使用してシェルスクリプトを実行し、正しく表示される場合は、シェルスクリプトが削除するのに十分な古い-n
ディレクトリを削除することをお勧めします。それではこれを呼び出しprune-dirs
て実行可能にしましょう。
#!/bin/bash
# date sign comment
# 2019-01-11 sudodus version 1.1
# 2019-01-11 sudodus enter the pattern as a parameter
# 2019-01-11 sudodus add usage
# 2019-01-14 sudodus version 1.2
# 2019-01-14 sudodus check if any parameter to the command to be performed
# Usage
usage () {
echo "Remove directories found via the pattern (older than 'datint')
Usage: $0 [options] <pattern>
Examples: $0 'follower*'
$0 -v -n 'follower*' # 'verbose' and 'dry run'
The 'single quotes' around the pattern are important to avoid that the shell expands
the wild card (for example the star, '*') before it reaches the shellscript"
exit
}
# Manage options and parameters
verbose=false
dryrun=false
for i in in "$@"
do
if [ "$1" == "-v" ]
then
verbose=true
shift
elif [ "$1" == "-n" ]
then
dryrun=true
shift
fi
done
if [ $# -eq 1 ]
then
pattern="$1"
else
usage
fi
# Command to be performed on the selected directories
cmd () {
echo rm -r "$@"
}
# Pattern to search for and limit between directories to remove and keep
#pattern='follower*'
datint=14 # days
tmpdir=$(mktemp -d)
tmpfil1="$tmpdir"/fil1
tmpfil2="$tmpdir"/fil2
secint=$((60*60*24*datint))
seclim=$(date '+%s')
seclim=$((seclim - secint))
printf "%s limit-in-seconds\n" $seclim > "$tmpfil1"
if $verbose
then
echo "----------------- excluding newest match:"
find . -type d -name "$pattern" -printf "%T@ %p\n" | sort |tail -n1 | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/'
fi
# exclude the newest match with 'head -n -1'
find . -type d -name "$pattern" -printf "%T@ %p\n" | sort |head -n -1 >> "$tmpfil1"
# put 'limit-in-seconds' in the correct place in the sorted list and remove the timestamps
sort "$tmpfil1" | cut -d ' ' -f 2- | sed -e 's/^/"/' -e 's/$/"/' > "$tmpfil2"
if $verbose
then
echo "----------------- listing matches with 'limit-in-seconds' in the sorted list:"
cat "$tmpfil2"
echo "-----------------"
fi
# create 'remove task' for the directories older than 'limit-in-seconds'
params=
while read filnam
do
if [ "${filnam/limit-in-seconds}" != "$filnam" ]
then
break
else
params="$params $filnam"
fi
done < "$tmpfil2"
cmd $params > "$tmpfil1"
cat "$tmpfil1"
if ! $dryrun && ! test -z "$params"
then
bash "$tmpfil1"
fi
rm -r $tmpdir
follower
現在のディレクトリをサブディレクトリを含むディレクトリに変更します。- ファイルの作成
prune-dirs
- 実行可能にする
2つのオプションで実行
-v -n
cd directory-with-subdirectories-to-be-pruned/ nano prune-dirs # copy and paste into the editor and save the file chmod +x prune-dirs ./prune-dirs -v -n
テスト
prune-dirs
以下のように、次のサブディレクトリがあるディレクトリでテストしました。find
$ find . -type d -printf "%T+ %p\n"|sort
2018-12-01+02:03:04.0000000000 ./follower1234
2018-12-02+03:04:05.0000000000 ./follower3456
2018-12-03+04:05:06.0000000000 ./follower4567
2018-12-04+05:06:07.0000000000 ./leader8765
2018-12-05+06:07:08.0000000000 ./bystander6789
2018-12-06+07:08:09.0000000000 ./follower with spaces old
2019-01-09+10:11:12.0000000000 ./follower7890
2019-01-10+11:12:13.0000000000 ./follower8901
2019-01-10+13:15:34.4094596830 ./leader1
2019-01-10+13:15:36.8336011960 ./leader2
2019-01-10+14:08:36.2606738580 ./2
2019-01-10+14:08:36.2606738580 ./2/follower with spaces
2019-01-10+17:33:01.7615641290 ./follower with spaces new
2019-01-10+19:47:19.6519169270 .
使用法
$ ./prune-dirs
Remove directories found via the pattern (older than 'datint')
Usage: ./prune-dirs [options] <pattern>
Examples: ./prune-dirs 'follower*'
./prune-dirs -v -n 'follower*' # 'verbose' and 'dry run'
The 'single quotes' around the pattern are important to avoid that the shell expands
the wild card (for example the star, '*') before it reaches the shellscript
実行-v -n
(詳細なテスト実行)
$ ./prune-dirs -v -n 'follower*'
----------------- excluding newest match:
"./follower with spaces new"
----------------- listing matches with 'limit-in-seconds' in the sorted list:
"./follower1234"
"./follower3456"
"./follower4567"
"./follower with spaces old"
"limit-in-seconds"
"./follower7890"
"./follower8901"
"./2/follower with spaces"
-----------------
rm -r "./follower1234" "./follower3456" "./follower4567" "./follower with spaces old"
より一般的なパターンを使用した詳細な練習
$ LANG=C ./prune-dirs -v -n '*er*'
----------------- excluding newest match:
"./follower with spaces new"
----------------- listing matches with 'limit-in-seconds' in the sorted list:
"./follower1234"
"./follower3456"
"./follower4567"
"./leader8765"
"./bystander6789"
"./follower with spaces old"
"limit-in-seconds"
"./follower7890"
"./follower8901"
"./leader1"
"./leader2"
"./2/follower with spaces"
-----------------
rm -r "./follower1234" "./follower3456" "./follower4567" "./leader8765" "./bystander6789" "./follower with spaces old"
オプションなしで実行(ディレクトリ削除の実際のケース)
$ ./prune-dirs 'follower*'
rm -r "./follower1234" "./follower3456" "./follower4567" "./follower with spaces old"
-v
「再試行」を実行
$ LANG=C ./prune-dirs -v 'follower*'
----------------- excluding newest match:
"./follower with spaces new"
----------------- listing matches with 'limit-in-seconds' in the sorted list:
"limit-in-seconds"
"./follower7890"
"./follower8901"
"./2/follower with spaces"
-----------------
rm -r
シェルスクリプトは「秒制限の上」ディレクトリを一覧表示せず、rm -r
コマンドラインのファイルを一覧表示しないため、操作は完了します(正しい結果です)。ただし、数日後にシェルスクリプトを再実行すると、一部の新しいディレクトリが「秒制限」を「超過」して削除されることがあります。