シェルスクリプトのすべてのパラメータを繰り返します。

シェルスクリプトのすべてのパラメータを繰り返します。

私はシェルスクリプトを作成しましたが、スクリプトに引数として渡された各ファイルの行数を印刷するループを実行する方法がわかりません。出力は次のとおりです。

2 lines in hello.sh
33 lines in /var/log/syslog

答え1

POSIXシェルを想定すると、ここでコマンドライン引数を含むforループを使用してループを実行する必要があります。"$@"

for filename in "$@"; do
    lines=$(wc -l < "$filename")
    printf '%u lines in %s\n' "$lines" "$filename"
done

すべての引用符を使用することは非常に重要です。スペースやその他の文字を含むファイル名を渡すことができます。

./my_script.sh /var/log/syslog "$HOME/My Dir with Spaces/a file with spaces.txt"

答え2

通常、スクリプトまたはシェル関数でコマンドライン引数を繰り返すには、次の手順を実行します。

for thing do
    commands using "$thing"
done

または

for thing in "$@"; do
    commands using "$thing"
done

この場合、コマンドラインで指定されたファイル名にリテラル改行が含まれていないと仮定すると、これに対して明示的なシェルループを実行する必要はありません。

wc -l -- "$@" | sed -E '$d;s/^[[:blank:]]*([[:digit:]]*)[[:blank:]]*(.*)/\1 lines in \2/'

これにより、すべてのコマンドライン引数が使用され、wc -lすべて実行されます。

出力を解析して、指定されたsedファイルの総行数を含む最後の行を削除します(使用$d)。wc -l行番号とファイル名をキャプチャし、その間に文字列を挿入して残りの出力lines inを目的の出力に変換します。

私自身のスクリプト.vimrcを実行すると、.profileファイル.mailrcが返されます。

8 lines in .vimrc
8 lines in .profile
4 lines in .mailrc

これにより、次wc -l -- "$@"のような出力が生成されます。

   8 .vimrc
   8 .profile
   4 .mailrc
  20 total

これは実際に必要なく、あなたのニーズに十分かもしれませんsed

答え3

#!/bin/bash

for file in "${@}"; do
    wc -l -- "${file}"
done

#!/bin/bashスクリプトを実行するプログラムです。

${@}位置引数。コマンドラインを介してスクリプトに提供する引数。

file引数で指定された変数を繰り返します${@}

wc -l -- "${file}"行数を印刷する外部コマンド(標準入力の行数を印刷する場合${file}を除く)${file}-

答え4

代替用途whileshift

while [ $# -gt 0 ] ; do
    printf '%u lines in %s\n' $(wc -l < "$1") "$1"
    shift
done

関連情報