find
フォルダ内の特定のファイルパターンを除いて、そのフォルダのサブフォルダには除外するコマンドが必要です。たとえば、除外したい場合、subdir1/subdir1.1/UndesiredFiles*.tgz
アスタリスクはフォルダ名の区切り文字を含む連続した文字と一致するため、以下は機能しません/
。
find * -not -path 'subdir1/subdir1.1/UndesiredFiles*.tgz'
上記では除外したくない次の項目を除外します。
subdir1/subdir1.1/UndesiredFilesAndMore/*.tgz
subdir1/subdir1.1/UndesiredFilesAndMore/StillMore/*.tgz
私はGnufind
バージョン4.9.0を使用しています。
ベストアンサー1
一部find
の実装では、シェルのglobパターンの代わりに正規表現(実装とオプション、または他の述語によってバリエーションが異なります)を使用することを除いて、同じ述語をサポートしています-regex
。非標準のBSDスタイル述語をサポートしている-path
ことを考慮すると、おそらくそれらの1つです。find
-not
LC_ALL=C find . ! -regex '\./subdir1/subdir1\.1/UndesiredFiles[^/]*\.tgz'
*
glob演算子(regexpと同じ.*
:0個以上の文字)をregexp [^/*]
(0個以上の文字を除く/
)に置き換えます。
正規表現はデフォルトで固定されているため、明示的または^
必須ではありません$
。
すべての文字に一致する正規表現演算子と同様に、リテラルのみに一致するようにエスケープを.
使用する必要があります\.
([.]
可能であっても)。 sはファイル名で非常に一般的な.
ので見落としがちです。.
LC_ALL=C
すべてのファイル名とディレクトリ名がユーザーロケールの有効な文字でのみ構成されることを保証できない場合は、通常必須です(これは-path
btwにも適用されます)。
BSDでは標準の基本正規表現を使用し、-regex
forやなどのオプションを使用して標準拡張正規表現に変更できます。 GNUの場合、デフォルトではこれはemacs正規表現の古代バージョンですが、他のさまざまなバージョンに変更される可能性があります。-E
grep
sed
find
-regextype
スルブ。それにもかかわらず、上記の特定の正規表現はどんな変形でも機能します。
find
サポートされていない場合は、次のことが-regex
できます。
LC_ALL=C find . ! '(' -path './subdir1/subdir1.1/UndesiredFiles*.tgz' \
! -path './subdir1/subdir1.1/*/*' ')'
つまり、1つ以上を含む一致を./subdir1/subdir1.1/UndesiredFiles*.tgz
除いてフィルタリングします。*
/
または、perl
以下をフィルタリングできます。
find . -exec printf '%s\0' {} + |
perl -l -0ne 'print unless m{^\Q./subdir1/subdir1.1/UndesiredFiles\E[^/]*\.tgz\z}'
ここでは、\Q...\E
内容を固定文字列として処理して正規表現演算子をエスケープする必要はありません。ここでは、正規表現を^
始めと終わりに固定する必要があります(正規表現は、末尾または末尾の改行がPerlで一致しないため、ファイルが「間違って」除外されます)。\z
$
$'UndesiredFiles.tgz\n'
(パスを引数として使用してコマンドを実行して置き換えprint
ますsystem "cmd", $_
)
一部(ほとんど)のfind
実装は-exec printf '%s\0' {} +
で置き換えることができます-print0
。一部のxargs
実装では、-0
またはオプションで-d '\0'
この出力形式をサポートしています。
find . -print0 |
perl -0 -lne 'print unless m{^\Q./subdir1/subdir1\.1/UndesiredFiles\E[^/]*\.tgz\z}' |
xargs -r0 cmd
-l
オプションが移動しました後ろに -0
出力レコード区切り記号も NUL です。
zsh
シェルを使用する場合はこれは必要ありませんfind
。次のことができます。
set -o extendedglob
print -rC1 -- **/*~subdir1/subdir1.1/UndesiredFiles[^/]#.tgz(ND)
ここで#
正規表現と同等のExtendedglobは次の*
とおりです。~
とは別に/まさかand演算子は、一致するグローバル拡張動作に(ND)
適用されますnullglob
(一致しない場合は何も拡張されません)と(隠しファイルを含む)。 matchの動作をさらに一致させるために、リストに修飾子を追加することもできます。dotglob
find
oN
N
o
find
print -rC1 --
print
r
■列です1
C
が、もちろん別のコマンドを使用したり、リストを繰り返すこともできますfor
。
**/*
(サブディレクトリの数に関係なく、すべての名前を持つすべてのファイルと一致、省略)このオプションが設定されていると、(*/)#*
省略できます。**
globstarshort
とにかく、これらすべては除外されますが./subdir1/subdir1.1/UndesiredFiles-whatever.tgz
、いいえ除外./subdir1/subdir1.1/UndesiredFiles-whatever.tgz/other/file
パターンを調整するか、-prune
find
述語を使用して除外する必要があります。