特定の文字列で終わるすべてのファイルを削除する

特定の文字列で終わるすべてのファイルを削除する

xシーケンスを含む約15,000の画像を含むディレクトリがあります。

scene1_000000.png
scene1_000001.png
scene1_000002.png
scene1_000003.png
scene1_000004.png
scene1_000005.png
scene1_000006.png
scene1_000007.png
scene1_000008.png
       .
       .
       .
       .
scene2_000300.png
scene2_000000.png
scene2_000001.png
scene2_000002.png
scene2_000003.png
scene2_000004.png
scene2_000005.png
scene2_000006.png
scene2_000007.png
scene2_000008.png
       .
       .
       .
       .
scene2_000300.png
       .
       .
       .
       .
scene50_000000.png
scene50_000001.png
scene50_000002.png
scene50_000003.png
scene50_000004.png
scene50_000005.png
scene50_000006.png
scene50_000007.png
scene50_000008.png
       .
       .
       .
       .
scene50_000300.png

各シーケンスの最初の150シーケンスを維持し、残りは削除したいと思います。そこで、各シーンに000000から000150までのシーケンスを提供します。

答え1

最新バージョンのbashでは、中括弧拡張を使用してこれを達成できます。

rm scene*_{000151..000300}.png

Bashの中括弧拡張は先行ゼロを処理します。

$ echo {000000..000005}.png
000000.png 000001.png 000002.png 000003.png 000004.png 000005.png

したがって、これを使用{000151..000300}して必要なファイルのリストを生成できます。

答え2

使用find:

find . -maxdepth 1 -type f \
         -name 'scene*.png' \
       ! -name '*_0000[0-9][0-9].png' \
       ! -name '*_0001[0-4][0-9].png' \
       ! -name '*_000150.png' -print -delete

現在のディレクトリからのみ削除したいすべてのファイルを見つけます。

さまざまな-nameフラグが次のタスクを実行します。

  1. 一致するもののみを選択してくださいscene*.png
  2. 範囲内の000000.pngファイル名をフィルタリング(選択項目から削除)します000099.png
  3. 範囲内の000100.pngファイル名をフィルタリングします000149.png
  4. フィルタリングしてください000150.png

...その後、ファイルを削除します(まだ考慮している場合)。これらのファイル(私たちが保持したいファイル)が削除されるのを防ぐために、2番目、3番目、4番目のテストは-name無効になります。find

実際の削除が行われる前に削除されたファイルの名前も印刷されます。

まず、削除して実行することをお勧めします-delete

答え3

存在するジッシュ、この<m-n>構文は、mとnの間の数値文字列と一致します。どちらもオプションです。したがって:

rm scene<->_<151->.png

scene*_(ワイルドカードで始めることもできますが、これにより、異なるパターンに基づいて名前付きファイルがある場合に<->予期しないコンテンツが一致するのを防ぐことができます。)*

答え4

少しスクリプトかもしれません。

echo '#!/bin/bash
# Test argument
if [ $# = 1 ]; then
  if [ -d $1 ]; then
    cd $1
  else
    echo "$1 is not a directory" >&2
    exit 1
  fi
fi

declare f      # filname
declare -i fc  # file counter
declare -i fcs # file conter for a scene
declare sn     # scene number
declare csn    # current scene number
declare -i dfc # delete file counter
declare -i pfc # preserve file counter

# Open logfiles
exec file-delete>>&3
exec file-preserve>>&4

for f in *; do
  ((fc++))
  sn=${f#scene}
  sn=${sn%_*}
  if [ "$sn" = "$csn" ]; then
    ((fcs++))
  else
    # New number scene
    fcs=1   
    csn=$sn
    dfc=0
    pfc=0
    echo
  fi
  if ((fcs > 150));then
    # Candidate for deleting
    echo "$f" >>&3
    ((dfc++))
  else
    # Preserve file
    echo "$f" >>&4
    ((pfc++))
  fi
  # Display in console
  echo -en "\r scene $csn preserve:$pfc delete:$dfc"
done
echo

# Closing logfile
exec 3>&-
exec 4>&-

echo "Files scaned : $fc"
wc -l file-delete
wc -l file-preserve
' > ~/scanfile

実行してください:

bash ~/scanfile [<pathdir>]

省略すると、現在のディレクトリで動作します。

何も削除せずに、スキャンしたディレクトリに2つのファイル(削除されたファイルとアーカイブされたファイル)を書き込みます。

確認したら、次のコマンドを使用して削除したいファイルを移動できます。

[cd <pathdir>]
mkdir tmp
while read; do mv -v $REPLY tmp; done < file-delete

結果が良ければ

rm -rf tmp
rm file-delete file-preserve

関連情報