I don't quite understand the example given from the man find
, can anyone give me some examples and explanations? Can I combine regular expression in it?
The more detailed question is like this:
Write a shell script, changeall
, which has an interface like changeall [-r|-R] "string1" "string2"
. It will find all files with an suffix of .h
, .C
, .cc
, or .cpp
and change all occurrences of string1
to string2
. -r
is option for staying in current dir only or including subdir's.
NOTE:
- For non-recursive case,
ls
is NOT allowed, we could only usefind
andsed
. - I tried
find -depth
but it was NOT supported. That's why I was wondering if-prune
could help, but didn't understand the example fromman find
.
EDIT2: I was doing assignment, I didn't ask question in great details because I would like to finish it myself. Since I already done it and hand it in, now I can state the whole question. Also, I managed to finish the assignment without using -prune
, but would like to learn it anyway.
ベストアンサー1
The thing I'd found confusing about -prune
is that it's an action (like -print
), not a test (like -name
). It alters the "to-do" list, but always returns true.
The general pattern for using -prune
is this:
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
You pretty much always want the -o
(logical OR) immediately after -prune
, because that first part of the test (up to and including -prune
) will return false for the stuff you actually want (ie: the stuff you don't want to prune out).
Here's an example:
find . -name .snapshot -prune -o -name '*.foo' -print
This will find the "*.foo" files that aren't under ".snapshot" directories. In this example, -name .snapshot
makes up the [conditions to prune]
, and -name '*.foo' -print
is [your usual conditions]
and [actions to perform]
.
Important notes:
結果を印刷するだけであれば、アクションを省略することに慣れているかもしれません
-print
。 を使用するときは通常、そうすることは望ましくありません-prune
。find のデフォルトの動作は、(皮肉なことに) 末尾以外のアクションがない場合、式全体をアクションと「and」することです。つまり、次のように記述します。
-print
-prune
find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
これは次のように書くことと同じです:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
つまり、削除するディレクトリの名前も出力されますが、これは通常、必要なことではありません。代わりに、
-print
必要な場合はアクションを明示的に指定した方がよいでしょう。find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
「通常の条件」が、プルーニング条件にも一致するファイルに一致する場合、それらのファイルは出力に含まれません。これを修正するには、プルーニング
-type d
条件に述語を追加します。たとえば、 で始まるディレクトリをすべて削除したいが(これは確かに少し不自然です。通常は、と正確に
.git
名前が付けられたものだけを削除する必要があります)、それ以外は のようなファイルを含むすべてのファイルを表示したいとします。次のように試すことができます。.git
.gitignore
find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
これは出力に含まれません。修正バージョンは次のとおりです。
.gitignore
find . -name '.git*' -type d -prune -o -type f -print # DO THIS
追加のヒント: の GNU バージョンを使用している場合はfind
、の texinfo ページに、find
その man ページよりも詳細な説明があります (ほとんどの GNU ユーティリティに当てはまります)。