次のコマンドを想定
search /home/user proc .h .c .txt ...
find
指定された名前で始まり、指定された拡張子の1つで終わるすべてのファイルをインポートするコマンドを使用してスクリプトを作成しています。
ループを使ってうまく構築しました。
directory=$1
fileName=$2
fileExtensions=""
for arg in "$@"
do
#skipping first and second argument
if [ $arg = $1 -o $arg = $2 ]; then
continue;
fi
fileExtensions+="${arg//.}\|"
done
#removing the last '|', otherwise regex parser error occurs
fileExtensions=${fileExtensions::-1}
find $directory -name "$fileName*" -regex ".*\.\($fileExtensions)"
正規表現を使用してこれを達成するためのよりエレガントな方法はありますか?
ご協力ありがとうございます!
ベストアンサー1
スクリプトは次のように単純化できます。
directory=$1
fileName=$2
shift 2
a="$*" b="${*#.}"
(( ${#a} - ${#b} - $# )) && echo "some extension(s) is(are) missing a leading dot." >&2
fileExtensions="$(IFS=\|; echo "${*#.}")"
find "$directory" -name "$fileName*" -regextype posix-egrep -regex ".*\.($fileExtensions)$"
デフォルトでは、findはemacs型の正規表現を受け入れ、その型を使用するにはいくつかのバックスラッシュが必要です\|
(たとえば、上記のように)。これは、他の種類の正規表現を使用することで回避できます。
先行点(存在する場合)を削除し、残りのすべての「位置引数」をサブシェルの実行に${*#.}
使用するように設定されたIFSの最初の文字値に関連付けます。|
変数の割り当てと「パラメータ拡張」で十分です。
編集する(( ${#a} - ${#b} - $# ))
パラメータリストに提供されているすべての拡張子がドットで始まることを確認するために使用されます。
${#a}
接続内のすべてのパラメータの文字数()(a=$*
)は、接続内のすべてのパラメータの文字数()(前の1つの点を削除)()にパラメータ数()を加えた
値と等しくなければなりません。 ${#b}
b=${*#.}
$#
${#a} == ${#b} + $#
すべての引数に前にドットがある場合。
算術テスト:
(( ${#a} - (${#b} + $#) ))
または:
(( ${#a} - ${#b} - $# )) && echo "missing leading dot(s)."
編集2
コマンドライン引数に指定された拡張リストはここで処理されます。
fileExtensions="$(IFS=\|; echo "${*#.}")"
内部と外部の動作方法は次のとおりです。
$* # This generates a string of all positional arguments using IFS.
からLESS=+'/Special Parameters' man bash
:
つまり、「$*」は「$1c$2c...」と同じです。ここで、cはIFS変数値の最初の文字です。
次に、「パラメータ拡張」を使用して各位置パラメータの前部を切り取ります。
${parameter#word} # used as ${*# } above.
からLESS=+/'parameter#word' man bash
:
引数が@または*の場合、パターン除去操作は各位置引数に順番に適用され、拡張は結果リストになります。
word
以前の拡張の点に設定され、.
すべての位置パラメータの前の点が削除されました。
この時点でIFSは|
文字で始まるため、文字は文字列を構築するために使用され、|
先にドットが削除されたパラメータリストの区切り文字として機能します。
この文字列は、印刷のためにechoコマンドで提供されます。
しかし、echoコマンドを実行する前に変数$IFS
は|
。
これはコマンド実行でラップされます$(…)
(終了時にIFSへの変更を忘れたサブシェルの作成)。
次に、文字列を変数に割り当てます。
fileExtensions="$(IFS=\|; echo "${*#.}")"
つまり、.c .h .txt
に変換しますc|h|txt
。