テキストファイルがあり、次のように配列を作成したいと思いますarray=["line1","line2",...]
。
これは私のテキストの最初の行です。
Hamlet
William Shakespeare
Edited Barbara B Mowat Paul Werstine
Michael Poston Rebecca Niles
Folger Shakespeare Library
httpwwwfolgerdigitaltextsorgchapter5playHam
Created Jul 31 2015 FDT version 092
Characters Play
line 17 POLONIUS father Ophelia Laertes councillor King Claudiusthis line substituted
GHOST
出力は次の形式でなければなりません。
lines=["Hamlet"
,"William Shakespeare"
,"Edited Barbara B Mowat Paul Werstine "
,"Michael Poston Rebecca Niles"
,"Folger Shakespeare Library"
,"httpwwwfolgerdigitaltextsorgchapter5playHam"
,"Created Jul 31 2015 FDT version 092"
,"Characters Play"
,"line 17 POLONIUS father Ophelia Laertes councillor King Claudiusthis line substituted","GHOST"]
答え1
ファイルに空白行が含まれていないとします。
mapfile -t array <file
各読み取り行から-t
改行文字を削除します。array
使用すると、その行から配列が作成されます。file
bash
結果を配列自体で望むのか、それとも表示中の配列のテキスト表現で欲しいのかは明確ではありません。
得るために特別な要求された出力:
mapfile -t array <file
printf '"%s"\n' "${array[@]}" | { mapfile -t arr; IFS=','; printf 'lines=[%s]\n' "${arr[*]}"; }
これにより、以前と同様に行が配列に読み込まれますarray
。次のprintf
ステートメントは、配列の各要素の周りに二重引用符を追加し、それを新しいコマンドに送信して、変更されたmapfile
データを新しい一時配列に読み込みますarr
。配列は、printf
二重引用符で囲まれた要素の間にカンマを挿入して、要求された方法でその要素をフォーマットするステートメントで使用されます。
代わりに使用してくださいawk
(シェル配列に行をまったく保存しないでください)。
awk -v OFS=',' '
{ line[NR] = $0 }
END {
for (i=1; i<=NR; ++i)
$i = "\"" line[i] "\""
printf("lines=[%s]\n", $0);
}' file
その後、各行をawk
配列として読み込みます。最後に、要素に二重引用符を追加し、それを出力フィールドに割り当てます(ループ内for
)。このprintf
ステートメントは、シェルコードの例とほぼ同じ方法で出力形式を指定します。 $0
フィールドを割り当てたばかりの現在のレコードを表します。
答え2
次のツールを使用してこれを実行できますsed
。
sed - e '
s/^[[:blank:]]*//;s/[[:blank:]]*$//
s/"/\\"/g;H;$!d;g
s/\n/","/g;s/.*/"&"/
' input
読み取ると、各行の先頭と末尾のスペースを切り捨てます。二重引用符をすべてエスケープします。予約済みスペースに追加され、最後の行が表示されると、すべての改行が配列要素の区切り文字に変わります。
答え3
IFS=$'\n'
array=( $(awk '{print "\"" $0 "\""}' input_file) )
~のためすべてLines input_file
、上から下へのawk
コマンド 代替コマンドは、次の操作を行います。
- 一対の二重引用符で行を囲みます。
- 改行文字で二重引用符で囲まれた行を終了します。
- 結果行を標準出力として印刷します。
しかし、、標準出力として印刷する代わりに、コマンド全体の置換をコマンドのawk
結果に置き換えます。置換はコマンド置換の結果です。
次に、コマンド置換の結果にトークン化を適用します。トークン化にはこの文字は含まれていませんが、IFS
この文字で終わるIFS
すべての文字シーケンスを一意の「単語」として認識します。したがって、この特別なケースでは、「単語」はinput_file
二重引用符のペアで囲まれたコマンドのすべての行ですawk
。
コマンド置換は最も外側の括弧のペアで囲まれているので、行)()
の結果awk
メモ:
- 配列が割り当てられたら、シェル変数を
IFS
元の値(スペース、タブ、および改行)にリセットできます。
答え4
sed - e '
s/^[[:blank:]]*//; # trim any leading blanks from the current line read in
s/[[:blank:]]*$//; # trim any trailing blanks from the current line read in
s/"/\\"/g; # escape any double quotes which might exist in the current line read in
H;1h; # append the current line to the hold space, in case of first store as is
$!d; # not yet EOF, drop everything and go back to reading the next line
g; # @ EOF, fetch the hold space: line1\nline2\nline3\n....\nlineEND
s/\n/","/g; # line1","line2","line3","....","lineEND
s/.*/"&"/; # "line1","line2","line3","....","lineEND"
' input