ディレクトリツリー内の最も古いファイルから最新のファイルまでを対話的に削除します。

ディレクトリツリー内の最も古いファイルから最新のファイルまでを対話的に削除します。

ステップ1では、ディレクトリツリー内の最も古いファイルを「見つける」ことを試みていますが、これは次のように解決しました。この質問

xargsここで、古いものから新しいものへとインタラクティブに削除するために使用したいと思います。

これはfind -type f -printf '%T+ %p\n' | sort | xargs -0 -d '\n' rm -i機能しません。別の投稿で見ました find . -type f -print0 | xargs -0 ls -rtが、xargs残念ながら追加しても機能しません。

pi@raspberrypi:/usr/share/doc/samba$ find . -type f -print0 | xargs -0 ls -rt | xargs -0  -d '\n' rm -i
    rm: remove write-protected regular file ‘./examples/LDAP/samba.schema.oc.IBM-DS’? rm: remove write-protected regular file ‘./examples/LDAP/samba-schema-netscapeds5.x.README’? rm: remove write-protected regular file ‘./examples/LDAP/samba-schema.IBMSecureWay’? rm: remove write-protected regular file ‘./examples/LDAP/samba.schema.gz’? rm: remove write-protected regular file ‘./examples/LDAP/samba-schema-FDS.ldif.gz’? rm: remove write-protected regular file ‘./examples/LDAP/samba.schema.at.IBM-DS.gz’? rm: remove write-protected regular file ‘./examples/LDAP/samba-nds.schema.gz’? rm: remove write-protected regular file ‘./examples/LDAP/samba.ldif.gz’? rm: remove write-protected regular file ‘./examples/LDAP/ol-schema-migrate.pl.gz’? rm: remove write-protected regular file ‘./examples/LDAP/get_next_oid’? rm: remove write-protected regular file ‘./README.Debian’? rm: remove write-protected regular file ‘./TODO.Debian’? rm: remove write-protected regular file ‘./NEWS.Debian.gz’? rm: remove write-protected regular file ‘./copyright’? rm: remove write-protected regular file ‘./changelog.Debian.gz’? rm: remove write-protected regular file ‘./examples/LDAP/README’?

これは権限の問題ではないことに注意してください。/usr/share/doc/samba実際のファイル名を投稿しないようにするために、例として使用しました。

Web を検索しても、再帰的 (ツリー全体) で、空のファイル文字を処理し、対話型でもあるスクリプトは見つかりませんでした。そこで、これを作成しました。これは、すべての種類の特殊文字を処理できるわけではありません。そのため、どのような改善でも受け入れられます。

#!/bin/bash
find -type f -printf '%T+ %p\n' | sort | head -n 3 > /tmp/1
cut -c32- /tmp/1 | awk '{print "rm -i", "\""$_"\""}'/tmp/2
bash /tmp/2

答え1

あなたのスクリプトで問題となる文字は"と改行だけです。ファイル名の改行についてはあまり心配する必要はありません。

たとえば、$$ファイル名に が含まれる別の一時ファイル名を使用することもできます。

そこで、改善点として、

#!/bin/bash
TMP1=/tmp/file1.$$
TMP2=/tmp/file2.$$
find -type f -printf '%T+ %p\n' | sort | head -n 3 > $TMP1
cat $TMP1 | sed 's/"/\\"/g;s/[^ ]* //;s/^/rm -i "/;s/$/\"/' >$TMP2
bash $TMP2
rm -f $TMP1 $TMP2

これにより、ファイル名の引用符が処理されるはずです。(注: スクリプトにはまだいくつかの問題があります。ただし、自分のホーム環境でこれを行うのは問題ありません。また、大文字の TMP は推奨されませんが、私はとにかくそうしています。)

注意:xargs -pファイル名にスペースが含まれている場合は機能しません。

答え2

もうすぐそこに着いたよ。

これはあなたが望むことを実行し、ファイル名の空白を処理します:

find -type f -printf '%T+ %p\n' | sort | cut -c32- | xargs -p -n1 -d '\n' rm

-p, --interactive: 各コマンド ラインを実行するかどうかをユーザーに確認し、端末から 1 行読み取ります。応答が y または Y で始まる場合にのみ、コマンド ラインを実行します。

-n max-args, --max-args=max-args: コマンドラインごとに最大 max-args 個の引数を使用します。

-d delim入力項目は指定された文字で終了します。

関連情報