ディレクトリからファイルをフィルタリングまたは抽出する方法は?

ディレクトリからファイルをフィルタリングまたは抽出する方法は?

次の形式のファイルがあります。

abc_abc_abc   
abc_abc_abc.1    
abc_bca_bca    
abc_bca_bca.1    
abc_bca_bca.2    
abc_cab    
abc

2つの下線付きのファイルをインポートし、.(ドット)や単一の下線などの他のファイルを除外したいと思います。

結果は次のとおりです。

abc_abc_abc
abc_bca_bca

答え1

あなたはそれを使用することができますfind

find . -name "*_*_*" -not -name "*.*"

サブディレクトリでも検索されます。これを望まない場合は、通常のファイルのみを必要に応じて追加-maxdepth 1してください。-type f

find . -maxdepth 1 -type f -name "*_*_*" -not -name "*.*"

以前-printf "%P\n"./

答え2

を使用するkshか、いくつかの二重否定を使用します(ここでは、下線が3つ以上のファイルも除外すると仮定します)。bash -O extglobzsh -o kshglob

printf '%s\n' !(!(*_*_*)|*_*_*_*|*.*)

zsh -o extendedglobそれによって~ とは別にオペレーター:

printf '%s\n' *_*_*~(*_*_*_*|*.*)

または、zshデフォルトの否定演算子を使用してください。

printf '%s\n' ^(^*_*_*|*_*_*_*|*.*)

2つ以上の下線を含むファイルが必要な場合は、上記の項目をそれぞれまたはまたは!(!(*_*_*)|*.*)*_*_*~*.*置き換えます。^(^*_*_*|*.*)

他のアプローチは次のとおりです!(*[._]*)_!(*[._]*)_!(*[._]*)(3つ以上の下線を許可する[_.]ように置き換えます)。.

答え3

簡単に言えば、bash(または配列をサポートするシェル)では次のようになります。

files=(???_???_???)

これは?ワイルドカード文字を使用して、示されているように名前付きファイルを選択します。これには、3文字、下線、3文字、下線、3文字が含まれます。xyz_qrs_t.1ただし、。

もっと洗練されたものは次のとおりです。

files=([^._][^._][^._]_[^._][^._][^._]_[^._][^._][^._])

...使用するもの[^ ... ] ワイルドカード構文。各文字には[^._]1文字が必要です。いいえピリオドまたはアンダースコア。 Mixには3つのバッチ3つを区切る2つの下線があります[^._]

これを繰り返します。

for f in "${files[@]}"; do printf "File: %s\n" "$f"; done

関連情報