スクリプトはURLを取得し、それを解析して必要なフィールドを探し、その出力をリダイレクトしてファイルfile.txtに保存します。出力は、フィールドが見つかるたびに新しい行に保存されます。
A Cat
A Dog
A Mouse
etc...
file.txt
を取得し、そこから新しいスクリプトで配列を作成します。すべての行は配列内の独自の文字列変数になります。これまで私は試しました:
#!/bin/bash
filename=file.txt
declare -a myArray
myArray=(`cat "$filename"`)
for (( i = 0 ; i < 9 ; i++))
do
echo "Element [$i]: ${myArray[$i]}"
done
このスクリプトを実行すると、空白の結果、単語が分割され、代わりに
Element [0]: A Cat
Element [1]: A Dog
etc...
私はこれを得ることになります:
Element [0]: A
Element [1]: Cat
Element [2]: A
Element [3]: Dog
etc...
各行の文字列全体が配列内の各変数と1対1で対応するように、以下のループを調整するにはどうすればよいですか?
mapfile
コマンドを使用します。
mapfile -t myArray < file.txt
エラーはfor
を使用しています-ファイルのlinesをループする慣用的な方法は次のとおりです。
while IFS= read -r line; do echo ">>$line<<"; done < file.txt
詳細については、 BashFAQ/005 を参照してください。
mapfile
およびreadarray
(同義)は、Bashバージョン4以降で使用できます。 Bashの古いバージョンを使用している場合、ループを使用してファイルを配列に読み込むことができます。
arr=()
while IFS= read -r line; do
arr+=("$line")
done < file
ファイルの最後の行が不完全(改行がない)の場合、次の代替手段を使用できます。
arr=()
while IFS= read -r line || [[ "$line" ]] do
arr+=("$line")
done < file
関連する:
これもできます:
oldIFS="$IFS"
IFS=$'\n' arr=($(<file))
IFS="$oldIFS"
echo "${arr[1]}" # It will print `A Dog`.
注意:
ファイル名の展開は引き続き発生します。たとえば、リテラル*
を持つ行がある場合、現在のフォルダー内のすべてのファイルに展開されます。したがって、ファイルにこの種のシナリオがない場合にのみ使用してください。
ファイルから各行を読み取り、それを配列に割り当てるだけです。
#!/bin/bash
i=0
while read line
do
arr[$i]="$line"
i=$((i+1))
done < file.txt
常に shellcheck を使用してコードを確認してください。多くの場合、正しい答えが得られます。この場合、 SC2207 は、スペースで区切られた値または改行で区切られた値を持つファイルを配列に読み込むことをカバーします。
array=( $(mycommand) )
mapfile -t array < <(mycommand)
IFS=" " read -r -a array <<< "$(mycommand)"
Shellcheckページには、これがベストプラクティスと見なされる理由が示されています。
この回答 は使用するように言っています
mapfile -t myArray < file.txt
何らかの理由でbash <4.xでmapfile
を使用する場合は、mapfile
に対して shim を作成しました。 bash> = 4.xを使用している場合は、既存のmapfile
コマンドを使用します
現在、オプション-d
および-t
のみが機能します。ただし、上記のコマンドにはこれで十分です。 macOSでのみテストしました。 macOS Sierra 10.12.6では、システムbashは3.2.57(1)-release
です。そのため、シムが役立ちます。 bashをhomebrewで更新したり、bashを自分でビルドしたりすることもできます。
この手法 を使用して、変数を1つの呼び出しスタックに設定します。