私が持っているスクリプトには 2 つの入力が必要です。1 つは でfilepath
、もう 1 つfilename
は find コマンドを使用してファイルの存在を確認するために使用されます。
#!/bin/bash
Filepath=$1
Filename=$2
if [ -z "$Filepath" ] && [ -z "$Filename" ]
then
echo "Requires Input"
elif [ ! -z "$Filepath" ] && [ ! -z "$Filename" ]
then
Found=`find "$Filepath" -iname "$Filename"`
if [ -z "$Found" ]
then
echo "Not Found"
else
echo $Found
fi
fi
これは期待どおりに完全に正常に動作します。後で、このスクリプトにさらにいくつかの条件を追加する必要がありました。つまり、filename
入力パラメータとして のみを取得した場合、以下に示すように、ファイルシステム全体でそのファイルを検索します。
find / -iname "$Filename"
また、入力パラメータのみがこのスクリプトに渡される場合はfilepath
、ファイル名パラメータも必要であるか、または単に出力される必要があることをエコーする必要があります。
答え1
私ならこうします:
#! /bin/sh -
pattern=${1?Please provide a file name}
shift
[ "$#" -gt 0 ] || set /
find "$@" -iname "$pattern" | grep '^' && exit
echo >&2 "Not found"
exit 1
つまり、名前( は、find
これをファイル名と一致するパターン ( のため大文字と小文字は区別されませ-iname
ん) として扱い、検索する正確なファイル名として扱わないことに注意してください) を最初の引数として使用します。その他の引数は検索するディレクトリまたはファイルであり、何も指定されていない場合は で検索します/
。
出力を変数に保存して最後に表示するのではなく、grep
パススルーとして使用し、ファイルが見つかった場合に true を報告します。
また、stdout ではなく stderr に「見つかりません」というメッセージを出力し、終了ステータスでファイルが見つからなかったことを報告しています。
@ThomasN が指摘したように、 にファイル/ディレクトリ名を確実に渡すことができないというよくある問題がありますfind
。 というディレクトリ内を検索する場合-delete
、that-script name -delete
たとえば を呼び出すと悲惨な結果になります。BSD ではfind
、 を呼び出す前に を実行することでこれを回避できますfind
。
for i do
set -- "$@" -f "$i"
shift
done
移植可能にするには(ただし、移植可能ではないことに注意してください)、次のように問題が発生する可能性のある相対パスを-iname
先頭に追加する必要があります。./
for i do
case $i in
(. | ./* | /*) ;; # /foo, ./foo are not a problem
(*) i=./$i
esac
set -- "$@" "$i"
shift
done
find "$@"...
ただし、これは出力に影響します ( の代わりに が表示されます./delete/name
) -delete/name
。