ファイルの異なる行を異なる変数に読み込む方法は?


14

テキストファイルのさまざまな行をさまざまな変数に読み取りたいです。例えば

input.txt

line1 foo foobar bar
line2 bar
line3 foo
line4 foobar bar

私はこの結果を変数に格納したいvar1var2var3及びvar4その結果

var1=line1 foo foobar bar
var2=line2 bar

等々。

誰かがそれがどのように行われたか教えてください。evalforループで使用しようとしました。うまくいかないようです。



3
これは悪いアプローチです。基本的にはセット変数への唯一の理由は、することですので、彼らと何かを、特にツールの膨大な数があるので、設計されたファイル内のテキストのすべての行で物事を行うには(Awkの、セッド、grepcut、ら。)、必要なことだけを行う方がはるかに優れています。シェルスクリプトでマイクロ管理しないでください。仕事を成し遂げるためのツールを調整します。
ワイルドカード

回答:


20

あなたがするだろう:

unset -v line1 line2
{ IFS= read -r line1 && IFS= read -r line2; } < input.txt

または:

{ line1=$(line) && line2=$(line); } < input.txt

lineめったにビルトインされておらず、ほとんどのシェルlineはコマンド置換を実装するためにforkする必要があるため、効率的ではありません。また、標準コマンドではなくなりました)。

ループを使用するには:

unset -v line1 line2 line3
for var in line1 line2 line3; do
  IFS= read -r "$var" || break
done < input.txt

または、変数の名前を次のように自動的に定義しますline<++n>

n=1; while IFS= read -r "line$n"; do
  n=$((n + 1))
done < input.txt

bash配列変数と、readarray行を配列に読み込む組み込み関数をサポートしていることに注意してください。

readarray -t line < input.txt

注しかし逆他のほとんどのシェルに、というbash配列のインデックスは0ではない1から始まる(から継承されたksh)ので、最初の行はになり${line[0]}ません、${line[1]}けれども(@Costasが示されているように、あなたが作ることができますreadarray(別名mapfile)indiceで値を書き始めます1(bash他のほとんどのシェルがスパース配列であることにも反する配列)と-O 1)。

参照:「IFS = read -r line」を理解しますか?


12

そのようなタスクに配列を使用することを提案します

mapfile -t -O 1 var <input.txt

あなたは、各ラインを持っているだろう${var[1]}${var[2]}というように


このワンライナーは非常にうまく機能します。私のために問題を解決しました。
マット・Zabojnik

0

これは厳密にあなたが求めたものではありませんが、あなたのニーズに合うかもしれません。Awkでデータをシリアル化できます。$ 1が有効な変数名でない場合、これは破損することに注意してください。

awk '
function quote(str,   d, m, x, y, z) {
  d = "\47"; m = split(str, x, d)
  for (y in x) z = z d x[y] (y < m ? d "\\" d : d)
  return z
}
{
  print $1 "=" quote($0)
}
' input.txt > /tmp/input.sh
. /tmp/input.sh

結果:

$ echo "$line1"
line1 foo foobar bar

これは非常に奇妙なコードです!入力ファイル全体をbashスクリプトに変換するためにawkを使用しているようです。私はquote()が何をしているのか漠然と考えています。よりわかりやすい変数名が役立ちます。物事についてもう少し説明してもらえますか?
ジョー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.