ユーザーにファイル名の入力を求められ、そのファイル名を持つシステム上のすべてのファイルを印刷するスクリプトを作成する必要があります。これまで私のscript.shには次のものがあります。
#!/bin/bash
echo "please enter filename"
read filename
if [ find . -name $filename ] //not sure if the condition is right
then
//print all files on the system with that file name
not sure what to put here
else
echo "file does not exist"
fi
助けてください、ありがとう!
答え1
次のようなものを使用できます。
#!/bin/bash
echo "please enter filename"
read filename
find . -name "$filename" | egrep '.*'
if [ "$?" -ne 0 ]
then
echo "file does not exist"
fi
答え2
特定の名前を持つすべてのファイル検索を使用する簡単な操作の場合、bash
それは必要ありません。このユーティリティは、find
実際に見つかったファイルに対して操作を実行する必要がある状況にfind
役立ちます。
シェルには、サブディレクトリを「再帰的に」一致させるbash
特別な**
パターンがあります。シェルオプションを設定してこのモードを有効にしますglobstar
。
#!/bin/bash
shopt -s globstar dotglob nullglob
pathnames=( ./**/"$1" )
if [[ ${#pathnames[@]} -gt 0 ]]; then
printf 'Found "%s"\n' "${pathnames[@]}"
else
printf 'Found no file named "%s"\n' "$1"
fi
./**/"$1"
これにより、現在のディレクトリまたはその下にあるスクリプトの最初のコマンドライン引数に対応するすべてのファイル名と一致するようにパターンが拡張されます。生成されたパス名は配列に保存されますpathnames
。その後、配列の長さをテストし、配列に何かが含まれている場合(配列の長さが0より大きい)、配列の要素が印刷されます。配列が空の場合、メッセージが印刷されます。
シェルオプションを使用dotglob
して、nullglob
シェルワイルドカードパターンが隠しファイルと一致することを確認し、パターンが何も一致しない場合、パターンは完全に削除されます。
このスクリプト(たとえば、試しているコード)は、通常のファイル、ディレクトリ、シンボリックリンク、または他の種類のファイルを区別しません。
このスクリプトをテストします。
$ bash ~/script.sh .zshrc
Found "./.zsh/.zshrc"
Found "./skel/.zshrc"
$ cd /etc
$ bash ~/script.sh .zshrc
Found no file named ".zshrc"
このスクリプトがない場合は、設定オプションfailglob
とglobstar
シェルオプションをbash
使用して、コマンドラインから直接スクリプトと同じ操作を効果的に実行できます。
$ shopt -s globstar failglob dotglob
$ echo ./**/.zsh
./.zsh
$ echo ./**/.zshrc
./.zsh/.zshrc ./skel/.zshrc
$ echo ./**/booo
bash: no match: ./**/booo