1から変数に格納された数まで実行されるforループを作成したいと思います。ただし、次のエラーが発生します。
構文エラー:ループ変数の誤った内容
これは私のスクリプトです。
#!/bin/bash
count_lines ()
{
local f=$1
l=`wc -l $f | sed 's/^\([0-9]*\).*$/\1/'`
}
echo "$0 counts the lines of code"
l=0
while [ "$*" != "" ]
do
count_lines $1
echo "$1: $l"
shift
done
for(( i= 0 ; i <= ${l} ; i++))
do
title=$(grep -oPm1 "(?<=<title>)[^<]+" <<< "$0")
echo "$title"
done
答え1
スクリプトが実行可能であることを確認し、コマンド(パスを含む)を入力してスクリプトを実行します。たとえば、スクリプトが呼び出されfoo
て現在ディレクトリにある場合は、次のように実行します。
./foo
エラーメッセージが表示されたら、同様のことをしていますsh foo
。コンピュータで使用されているforループ構文をサポートしていない他のシェル(おそらくダッシュ)がありますsh
。を実行すると、最初の行に記載されているbashシェルによってスクリプトが実行されます。bash
sh
./foo
スクリプトにはいくつかの奇妙な部分があります。
- 変数の置換には常に二重引用符を使用してください。:
"$1"
、、、"$f"
など。 この
while [ "$*" != "" ] …
ループは、スクリプトパラメータを繰り返す非常にバイパス的な方法です。シンプルで慣用的な方法は次のとおりです。for x; do count_lines "$x" done
または
for x in "$@"; do count_lines "$x" done
- 何をしたいのかわかりません
title=$(grep -oPm1 "(?<=<title>)[^<]+" <<< "$0")
。"$0"
スクリプトパスなので、(?<=<title>)[^<]+
スクリプトパスから正規表現を検索していますが、これは意味がありません。
答え2
私の考えの主な問題は、ファイルが実際に存在するかどうかをテストせずにl
ループに無効なカウントを取得することですfor
。
いくつかのアイデアを得るには、この(非常に修正された)同様のスクリプトを見てください。
#!/bin/bash
count_lines() {
if [[ -r $1 ]]; then # if the file exist.
l="$(wc -l "$1")" # count the number of lines.
l="${l%%[^0-9]*}" # remove anything that is not a digit from the end.
else
l=0
fi
}
echo "$0 counts the lines of code"
for file; do # while there is an argument.
count_lines "$file" # execute the function above
echo "$file: $l" # print the number of lines.
done
echo "$(grep -oPm1 "(?<=<title>)[^<]+" "$0")"
ファイル内をl
見つけるためにコマンド(grep)を実行したい理由を理解できません。title
一度でも十分です。
また、grepコマンドは外部ファイルではなくスクリプトを読み込んでいます。
Gilesが言ったように、コードを真剣に修正し、新しい質問を投稿してください。