次のスクリプトを使用すると、ユーザーは --header を選択し、file* をファイル名として挿入して、すべての有効なファイルにヘッダーを追加できるようにします。
#!/bin/bash
case "$1" in
--header )
for filename in "$@"
do
sed -i -e '1 e cat header' "$filename"
done
;;
--footer )
footer=~/dev/sed/footer
for filename in "$@"
do
cat "$footer" >> "$filename"
done
;;
esac
./tool --header file* を実行するためにツールを実行すると、次のエラーが発生します: sed: 認識できないオプション '--header'
$ @変数が最初の変数入力(--header)と一致しようとしているため、これが発生することを知っていますが、それを停止する方法がわかりません。
答え1
$ @から最初の要素を削除するには、を使用しますshift
。
#!/bin/bash
opt=$1
shift
case "$opt" in
--header )
for filename in "$@" ; do
sed -i -e '1 e cat header' "$filename"
done
;;
--footer )
footer=~/dev/sed/footer
for filename in "$@" ; do
cat "$footer" >> "$filename"
done
;;
esac
答え2
問題は、ループを実行するときに"$@"
オプションがまだループしているリストの最初の要素であることです。繰り返す前に$@
with の最初の要素を削除できます。shift
私はコマンドラインの解析と操作を分離することを好みます。
#!/bin/sh
unset do_header
unset do_footer
# loop until end of valid options...
while true; do
case $1 in
--header) do_header=1 ;;
--footer) do_footer=1 ;;
*) # assume end of options
break
esac
shift # we have processed a valid option, shift it off the list
done
# create a temporary file that we will use multiple times
tmpfile=$(mktemp)
# remove temporary file on normal exit (in bash, also on TERM/INT)
trap 'rm -f "$tmpfile"' EXIT
# For each file, copy it to the temporary file,
# then add header and footer as requested.
# Since we clobber the original file with the redirection,
# we won't be modifying permissions on the file.
# At this point, the valid options (any number of
# --header and --footer options) have been shifted off
# the list of arguments, so the $@ array now presumably only
# contains pathnames of files that are to be modified.
for pathname do
cp -- "$pathname" "$tmpfile"
cat ${do_header:+"header"} "$tmpfile" ${do_footer:+"footer"} >$pathname
done
これにより、単一の呼び出しでヘッダーとフッターをファイルセットに追加できます。
変数が設定されていて空でない場合、パラメータ置換は${var:+word}
拡張されます。word
var
答え3
bashを使用している場合、他のオプションは次のとおりです。
for filename in "${@:2}"
これは2番目の引数から始まり、引数が与えられます。 POSIXではこれを指定しないため、一部のシステムではこれをサポートしていない可能性があります。一部のシェルは同じ機能を持っていますが、他の構文を使用できます。