Bash:標準入力またはコマンドライン引数の行を繰り返すきちんとした方法は何ですか?

Bash:標準入力またはコマンドライン引数の行を繰り返すきちんとした方法は何ですか?

Bashスクリプトがあり、stdinの行を繰り返したり、渡された各引数を繰り返したい。

2つのループを持つ必要がないようにこれを書くためのきちんとした方法はありますか?

#!/bin/bash

# if we have command line args... 
if [ -t 0 ]
then
  # loop over arguments
  for arg in "$@" 
  do
    # process each argument
  done
else
  # loop over lines from stdin
  while IFS= read -r line; do
    # process each line
  done
fi

編集:私はこれを頻繁に実行したいのですが、常に2つのループを作成してから関数を呼び出すので、単一ループを使用する一般的なソリューションを探しています。それでは、stdinを配列に変換して代わりに単一のループを使用できますか?

ベストアンサー1

ループに関するデータを生成しますwhile read

#!/bin/sh

if [ "$#" -gt 0 ]; then
    # We have command line arguments.
    # Output them with newlines in-between.
    printf '%s\n' "$@"
else
    # No command line arguments.
    # Just pass stdin on.
    cat
fi |
while IFS= read -r string; do
    printf 'Got "%s"\n' "$string"
done

concatループをまたは同様のものに置き換えて例を実行できます。while readtr '\n' ','

また、-tテストはコマンドライン引数があるかどうかを示していません。


または、処理両方コマンドライン引数と標準入力(シーケンス):

#!/bin/sh

{
    if [ "$#" -gt 0 ]; then
        # We have command line arguments.
        # Output them with newlines in-between.
        printf '%s\n' "$@"
    fi

    if [ ! -t 0 ]; then
        # Pass stdin on.
        cat
    fi
} |
while IFS= read -r string; do
    printf 'Got "%s"\n' "$string"
done

または、一部の人が好きな短縮表記を使用してください。

#!/bin/sh

{
    [ "$#" -gt 0 ] && printf '%s\n' "$@"
    [ ! -t 0 ]     && cat
} |
while IFS= read -r string; do
    printf 'Got "%s"\n' "$string"
done

おすすめ記事