見つけて反応する必要があるかなり複雑なファイルセットがあります(たとえば、テキストファイルにコピーされたパス)。
たとえば、
find / \( -iname "*ssh*" -or -iname "*scp*" \) \( -not -path -"/run" -not -path "/rw/*" -and -not -path "/home/*" -and -not -path "*/qml/*" \) >> ~/files.txt
ここでは、「ssh」と「scp」に関連するすべてのファイルまたはフォルダを検索したいが、/runまたは/rwディレクトリにはありません。
ここにさらに条件を追加したいのですが、コマンドが長すぎます。正規表現でこれをどのように実行できますか?
答え1
以下を使用して、そのディレクトリ内のファイルをフィルタリングするよりもまったく除外したいディレクトリに入れないことをお勧めします! -path <pattern>
。
LC_ALL=C find / \
'(' \
-path /run -o -path /rw -o -path /home -o -path '*/qml' \
')' -prune -o '(' \
-name '*[sS][hH][hH]*' -o -name '*[sS][cC][pP]*' \
')' -print
ここではPOSIX構文が使用されますfind
。 GNUの場合は、find
次のようになります。
LC_ALL=C find / -regextype posix-extended \
-regex '/home|/rw|.*/qml' -prune -o \
-iregex '.*s(cp|sh)[^/]*' -print
BSDを使用すると、次のようなものを使用してPOSIX EREを取得できますfind
。-E
grep
sed
LC_ALL=C find -E / \
-regex '/home|/rw|.*/qml' -prune -o \
-iregex '.*s(cp|sh)[^/]*' -print
答え2
ここに改行があるバージョンがあり、読みやすく、一部の誤字が修正されました。私はGNUルックアップを想定していますが、いくつかの修正はほとんどのBSDクエリでも機能します。
find / \
\( -iname "*ssh*" -or -iname "*scp*" \) \
\( -not -path "/run/*" \
-not -path "/rw/*" \
-not -path "/home/*" \
-not -path "*/qml/*" \) \
>> ~/files.txt
これで、少し簡単にするために-iname "*ssh*" -or -iname "*scp*"
正規表現で書くことができます。たとえば、次のようになります。
find ... \
-regextype posix-extended \
-iregex '.*(ssh|scp)[^/]*' \
...
これで名前を簡単に追加できます(ssh|scp|rsync|...)
。
これらの-not -path
テストは、次のように正規表現で組み合わせることができます。
find ... \
-not -regex '(/run|/rw|/home|.*/qml)/.*'
ただし、find
以下を使用しないと、これらのディレクトリを探索するのにまだ時間がかかります-prune
。
find / \
-regextype posix-extended \
-not \( -regex '(/run|/rw|/home|.*/qml)/.*' -prune \) \
-iregex '.*(ssh|scp)[^/]*' \
>> ~/files.txt