web-dev-qa-db-ja.com

ls grepとrmを使用してディレクトリ内のファイルを削除します

私はこの行で私のプロジェクトルートにbashファイルを持っています

$ ls | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs rm -f

上記の行は、プロジェクトルートからすべての.txtファイルを削除しますが、すべての.txtファイルを別のフォルダーにプッシュすると、たとえばprocess_logs /で、lsgrepおよびrmを使用して同じコマンドを試します動作しません。

これは私が試したものですが、process_logsディレクトリのファイルを削除するために機能しませんでした。

 $ ls process_logs/ | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs rm -f

N.B:ディレクトリからファイルを削除するためにls process_logs/ | grep -P '^*.txt$' | xargs rm -fのような単純な正規表現パターンを使用してコマンドを試しましたが、機能しません。

2
Always Sunny

代わりにfindを使用してください。 findを再帰的にしたくない場合は、深度オプションを使用できます。

find /process_logs -maxdepth 1 -mindepth 1 -type f -name 'some_Shell_glob_pattern_here' -delete

lsは人間が読み取れるバージョンのファイル名を出力するため、lsは必ずしも正確ではないため、lsの出力を解析することはお勧めしません。実際のファイル名と一致しない場合があります。詳細は 解析ls wikiの記事を参照してください。

2
jordanm

単純なシェルのファイル名展開パターンがある場合は、それを使用してください。

例えば。 (*は、より正確なパターンに置き換えることができます)、

rm -f process_logs/*.txt

または、数十万のファイルがある場合は、xargsを使用します。

printf '%s\0' process_logs/*.txt | xargs -0 rm -f

あなたが絶対に必要正規表現を使用する場合、GNU findはそれを

find process_logs -maxdepth 1 -type f -regex '\.txt$' -delete

-regex述語は、末尾のファイル名部分だけではなく、完全なパス名と一致することに注意してください(これが、式を$でパス名の末尾に固定した理由です)。 GNU findマニュアルの-regextypeオプションも参照してください。

1
Kusalananda

私はfindを使用することをお勧めしますに同意します。しかし、コマンドが機能しない理由を追加したいと思います。

あなたのコマンド:

$ ls process_logs/ | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs rm -f

lsはファイル名を出力しますパスなし。ただし、rmへのパスは追加しません。そのため、現在のルートディレクトリのサブディレクトリからファイル名を削除しようとします。

試す

$ cd process_logs/; ls | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs rm -f

または

$ ls process_logs/ | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs -i rm -f "process_logs/{}"
1
pLumo