ディレクトリ内の拡張子がpdfのファイルを除くすべてのファイルを削除します


50

次を含むディレクトリがあります。

x.pdf
y.zip
z.mp3
a.pdf

私は別に、すべてのファイルを削除したいx.pdfa.pdf。ターミナルからこれを行うにはどうすればよいですか?サブディレクトリがないため、再帰は必要ありません。

回答:


63
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
  • 最初のコマンドは、ファイルを削除するディレクトリに移動します
  • 2番目のコマンドは.pdf、ファイル名で終わるファイルを除くすべてのファイルを削除します

たとえばtemp、ホームフォルダーに呼び出されるディレクトリがある場合:

cd ~/temp

その後、ファイルを削除します。

find . -type f ! -iname "*.pdf" -delete

これにより、を除くすべてのファイルが削除されますxyz.pdf

これら2つのコマンドを組み合わせて、次のことができます。

find ~/temp -type f ! -iname "*.pdf" -delete

.現在のディレクトリです。最後にある!ファイル以外のすべてのファイルを取得することを意味します.pdf-type fディレクトリではなくファイルのみを選択します。-delete削除することを意味します。

注:このコマンドは、現在のディレクトリとすべてのサブディレクトリ内のすべてのファイル(pdfファイルを除き、隠しファイルを含む)を削除します。!前に来なければなりません-name。単純に-nameのみ含まれます.pdfが、-iname両方が含まれます.pdfし、.PDF

サブディレクトリではなく、現在のディレクトリでのみ削除するには、次を追加し-maxdepth 1ます。

find . -maxdepth 1 -type f ! -iname "*.pdf" -delete

答えてくれてありがとう。構文を少し理解してもらえますか?.「と」を意味する?!-name除外」は、名前パラメータで除外することを意味し-delete、検索時に実行するアクションですか?「* .pdf」以外のすべてを探して削除しますか?または私は誤解しましたか?
ジェセノトン14

.現在のディレクトリを意味します。最後にある!ファイル以外のすべてのファイルを取得することを意味します.pdf-delete削除することを意味します。私は今明確ですか?
エドワードトーバルズ14

@terdon Starkersには、サブdirectories.wait病気編集私の答えは、より幅広いがないようにと言われている
エドワード・トーバルズ

+1 -maxdepth 1最初からパラメータを含める必要がありました。次に、再帰的に削除する場合に備えて、パラメーターを削除することをお勧めします。
Tulainsコルドバ14

3
これ-inameにより-name、の代わりにを使用する必要がある.PDFことに気が付きました。そうしないと、拡張子が付いたファイルがすり抜けます。
ムル14

43

bash拡張シェルグロブ、あなたは以外の拡張子を持つすべてのファイルを削除することもできます.pdf使用して

rm -- *.!(pdf)

@ptsで述べたように、--文字はコマンドオプションの終わりを示し、ファイルが文字で始まるまれな場合にコマンドを安全にします-

拡張子のないファイルと拡張子が以外のファイルを削除する場合は.pdf、@ DennisWilliamsonが指摘したように、

rm -- !(*.pdf)

拡張グロビングはデフォルトで有効にする必要がありますが、そうでない場合は次を使用して有効にすることができます

shopt -s extglob

特にスクリプト内でこれを使用する場合、式が何にも一致しない場合(つまり、ディレクトリに非pdfファイルがない場合)、デフォルトではグロブが展開されずに渡されることに注意することが重要ですrm次のようなエラーが発生するコマンド

rm: cannot remove `*.!(pdf)': No such file or directory

nullglobシェルオプションを使用してこのデフォルトの動作を変更できますが、独自の問題があります。より詳細な議論については、NullGlob-Greg's Wikiを参照してください


IMOへのより良いアプローチ。
Takkat 14

拡張子のないファイルはどうですか?FWIW、zshではrm *~*.pdf
エミルイェジャベク14

1
かっこ内にドットを配置します。
デニスウィリアムソン14

4
ああ、アスタリスクも中に入れる必要があります!(*.py)。また、おそらく、OPが ".pdf"ファイルのみを残したい場合は、拡張子のないファイルも削除して無視しないでください。
デニスウィリアムソン14

1
このアプローチは、受け入れられている答えよりも単純で洗練されています。
ピーター14

18

ゴミ箱に削除

$ cd <the directory you want>
$ gvfs-trash !(*.pdf)

または経由でmvコマンド(それが.trashinfo情報を記録していないので、この方法であなたがゴミ箱からそれを復元することはできませんので、この手段は、あなたがにファイルを移動次のようにそれはあります)。

mv !(*.pdf) ~/.local/share/Trash/files

6
このアプローチは、直接使用するよりはるかに安全ですrm
セス14

14

最も簡単な方法:別のディレクトリをどこかに作成します(再帰的にではなく、1つのディレクトリのみを削除する場合は、サブディレクトリでもかまいません)。すべての.pdfをそこに移動します。他のすべてを削除します。PDFを戻します。中間ディレクトリを削除します。

素早く、簡単に、あなたがやっていることを正確に見ることができます。中間ディレクトリがクリーンアップするディレクトリと同じデバイス上にあることを確認してください。そうすれば、移動はコピーではなく名前変更になります。


4
+1初心者ユーザーにとって意味のあるコメントの場合も、意図せずにファイルを削除することはほとんどありません。
トログナンダー14

4

bashのGLOBIGNOREを使用します。

GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE

bashのmanページから:

GLOBIGNORE:

            セットを定義するコロンで区切られたパターンのリスト
            パス名の展開によって無視されるファイル名のリスト。

簡単なテスト:

mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *

出力:

y.zip
z.mp3

3

注意して構成する:xargsを使用する

私がとても気をつけてくれるので、私が好きなアプローチがあります:削除したいファイルだけを表示する方法を作成し、それをrm使用して送信しますxargs。例えば:

  • ls すべてを見せてくれます
  • ls | grep pdf保持したいファイルを表示します。うーん。
  • ls | grep -v pdf反対を示しています:私が保持したいものを除くすべて。つまり、削除したいもののリストが表示されます。危険なことをする前にこれを確認できます。
  • ls | grep -v pdf | xargs rmそのリストをrm削除のために正確に送信します

私が言ったように、私は主にそれが提供する安全性のためにこれが好きです:rm *私にとって偶然ではありません。他の2つの利点:

  • 構成可能です。lsまたはfindを使用して、必要に応じて初期リストを取得できます。リストを絞り込むプロセスでは、別のgrepものawk、別のもの、その他何でも使用できます。名前に色が含まれているファイルのみを削除する必要がある場合は、同じ方法で作成できます。
  • 各ツールを主な目的に使用できます。フラグを受け入れることを覚えておく必要はなく、find検索とrm削除に使用することを好みます。また、これを行うと、別のソリューションを作成できます。多分代わりに、ファイルをゴミ箱に移動するコマンドを作成して(「削除」を許可)、代わりにそのファイルにパイプすることができます。そのオプションをサポートする必要はなく、単にパイプするだけです。find-deletermtrashrmfind

更新

@paboukによるコメントを参照して、ファイル名の改行、などのファイル名など、エッジケースを処理するためにこれを変更する方法を確認してくださいmy_pdfs.zip


4
ここで3つの問題に気付きました。a pdf名前に任意の場所を含むファイルを除外します。--- b)接尾辞の文字のいずれかが大文字の場合、PDFファイルを削除します。--- c)の出力を使用するのは得策ではありませんls。改行を含むファイル名では機能しません。の一部の実装はls、特殊文字を置き換える(例:タブ)?。---使用することをお勧めしますfind -maxdepth 1 -print0。(ではないので、短いようls:) -----解決するために)、およびb)使用grep -vi '\.pdf$'---完全な(しかし、GNUのみ)解決策:find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
pabouk

1
ソリューションは複数の手動反復を伴う「対話型」プロセスであると理解しましたが、チェックはファイルの長いリストではほとんど使用できず、上記の問題は見落としやすいミスをもたらす可能性があります。
pabouk

1
@paboukの良い点; 現実の世界は常に物事を複雑にし、あなたの修正は役に立ちます。:)しかし、私はまだこの全体的なアプローチが最善だと思います。ファイルが多すぎてすべてを視覚的に確認でき| head -20ない場合は、少なくともそのファイルがおおよそ正しいかどうかを確認できますが、ただの場合rm my_pattern、大きな間違いを見つける機会はありません。
ネイサンロング

1
削除する前にファイルを表示し、-deleteを省略して、find . -type f ! -name "*.pdf"コンソールへの印刷、またはlessまたはファイルへのパイプに使用することができます。[そして、必要に応じてpaboukのコメントのようにxargsにパイプして(奇妙なファイル名には-print0 | ... -0を使用)]
Xen2050 14

3

私は通常、対話型Pythonインタープリターからこのような問題を解決します。

mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
...   if not f.endswith('.pdf'):
...     os.remove(f)

findまたはの付いた1ライナーよりも長い場合がありますが、xargs非常に回復力があり、最初に調査する必要なく、それが何をするかを正確に知っています。


すべての追加のラインでますます神経質に人のために、我々は可能性が一つにそれを作る:for item in [f for f in os.listdir('.') if not f.endswith('.pdf')]: os.remove(item)
ジェイコブVlijm

python -c "import os; for f in os.listdir('.'): if not f.endswith('.pdf'): os.remove(f)"
mic_e 14

[os.remove(f) for f in os.listdir('.') if not f.endswith('.pdf')]
mic_e 14

いいね!2番目のものは構文エラーになりますが、理由はわかりません。
ジェイコブVlijm 14

奇妙な; 私のシステムではpython 3.4とpython 2.7の両方で動作します。
mic_e 14

2

この質問に対するより良い回答(以前の回答と比較して)は、強力なfileコマンドを使用することです。

$ file -i abc.pdf
abc: application/pdf; charset=binary

今あなたの問題:

cd <the directory you want to search in>
for var in ./*
do
if file -i "$var" | grep -q 'application/pdf\;'
then
echo "$var"
fi
done

forコマンドの仕事は、変数の形式で現在のディレクトリ内のファイルを与えることです$varif-thenコマンドは、0from file -i "$var" | grep -q 'application/pdf\;'コマンドの終了ステータスを取得してpdfファイルの名前を出力します。pdfファイルが0見つかった場合のみ、終了ステータスを表示します。


1
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')

警告!最初に試してみてください

ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')

2
うーん、これは非常に多くの点で欠陥があります:smallo.ruhr.de/award.html#ls、smallo.ruhr.de/award.html#grepそして空白や特殊文字を含むファイル名を完全に無視します。
デビッドフォースター14

1
あなたは本当に使うべき-igrep大文字と小文字を区別しないマッチングのために。
ムル14

1
rm -i -- !(*@(a|x).pdf)

、として読んでないすべてのファイルを削除しますa.pdfx.pdf

2つの拡張グロブを利用することによって、この作品は、外側は!()それ自体がグロブは、以上のいずれかと一致しなければならないことを必要含まグロブ否定するaか、x前にパターン.pdf接尾辞。glob#extglobを参照してください。

$ ls -a
.dotfile1 .dotfile2 a.pdf x.pdf y.zip z.mp3

$ echo -- !(a.pdf)
-- x.pdf y.zip z.mp3

$ echo -- !(x.pdf)
-- a.pdf y.zip z.mp3

$ echo -- !(a.pdf|x.pdf)
-- y.zip z.mp3

$ echo -- !(@(a|x).pdf)   # NOTE.that this matches the .dotfiles* as well
-- . .. .dotfile1 .dotfile2 y.zip z.mp3

$ echo -- !(*@(a|x).pdf)  # but this doesn't
-- y.zip z.mp3

$ echo rm -i -- !(*@(a|x).pdf)
rm -i -- y.zip z.mp3

1

ポータブルシェルウェイ

$ ksh -c 'for i in ./*; do case $i in *.pdf)continue;; *)rm "$i";; esac;done'

かなり多くのPOSIXおよび任意のボーンスタイルのシェルとの互換性(kshbashdash)。ポータブルスクリプトや、bash拡張シェルグロビングを使用できない場合に適しています。

perl:

$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'                                                             

またはわずかにクリーナー:

$ perl -le 'opendir(my $d,"."); map{ unlink $_ } grep(-f "./$_" && !/.pdf/ , readdir($d));closedir $d'

代替パイソン

python -c 'import os;map(lambda x: os.remove(x), filter(lambda x: not x.endswith(".pdf"),os.listdir(".")))'

0

削除するものに注意してください!

削除しようとする前にテストする安全な方法は、最初にでテストlsすることです。いくつかのキャッチされていない動作により、不要なファイルが削除される可能性があります。また、ディレクトリの外で直接行うことができます。lsに似ているrmので:

ls sub/path/to/files/!(*.pdf)

これがリストされます

y.zip
z.mp3

そして今、あなたはあなたが削除しているものを見ることができ、それらを安全に削除することができます:

rm sub/path/to/files/!(*.pdf)

以上です。Yoはワイルドカード*を使用して、プログラミングコースドキュメントのみを保持するように、より選択的にすることができます。

rm sub/path/to/files/!(*programming*)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.