Bashのforループ

Bashのforループ

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シェルによってスクリプトが実行されます。bashsh./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が言ったように、コードを真剣に修正し、新しい質問を投稿してください。

関連情報