各要素がファイルの1行に等しいように、配列をスクリプトにファイル引数として提供するにはどうすればよいですか?

各要素がファイルの1行に等しいように、配列をスクリプトにファイル引数として提供するにはどうすればよいですか?

bashスクリプトは、引数がファイルであると想定していると仮定します。しかし、私たちはbash配列を持っており、配列の要素である行を含むファイルがあるかのように、何らかの方法でスクリプトを引数としてその配列を提供しようとしています。何をすべきか知りたいです。

myscrpt簡単な例として、ファイルパラメータを必要とする単一のコマンドを含むスクリプトがあります。

cat $1

配列があります

arr=( 1 3 5 )

arr引数が実際に内容が次のファイルであるかのようにスクリプトに引数として提供するにはどうすればよいですか?

1
3
5

効果的ですか myscript <(echo "${arr[@]}")

ありがとうございます。

答え1

bashシェルまたは配列をサポートする他のシェルを使用している場合は、"${var[@]}"タイプ設定を使用できます。

a=(one two 'three four' five)
printf "%s\n" "${a[@]}"

printfたとえば、必要な要素に1行に1つの要素をパイプします。

printf "%s\n" "${a[@]}" | myscript

配列拡張を二重引用符で引用することは本当に重要です。それ以外の場合は、@文字が処理され、*配列拡張が空白で区切られた単語として(誤って)処理されます。

答え2

したがって、スクリプトがあります(少し変更して、珍しいファイル名を持つファイルからの読み取りをサポートするために拡張子の#!周りに-lineと引用符を追加します)。$1

#!/bin/sh
cat "$1"

今度は配列を使ってこのスクリプトを呼び出そうとします。

arr=( 1 2 3 4 5 )

これにより、(スクリプトが実行する)ファイルを読み取るのではなく、配列から改行で区切られた値を読み取って次のように生成します。

1
2
3
4
5

出力に?

次のことができます。

printf '%s\n' "${arr[@]}" | ./script -

または

printf '%s\n' "${arr[@]}" | ./script /dev/stdin

これにより、スクリプトに読み取るファイルに、-またはが渡されます。標準入力と解釈され/dev/stdin、与えられると標準入力でも読み込まれます。cat-/dev/stdin

printfデータは、配列から改行で区切られた要素として提供される標準入力として提供されます。

同じ効果があるでしょう

( IFS=$'\n'; sh ./script.sh - <<<"${arr[*]}" )

ここでは、文字列を介してデータが提供されます。を使用して、"${arr[*]}"配列の要素を$IFS最初の文字(改行文字に設定)で区切られた文字列に連結します。IFS周辺環境の変更を避けるために、ここではサブシェルを使用しています。

関連情報