各テキスト行をコンマで区切って配列に配置するにはどうすればよいですか?

各テキスト行をコンマで区切って配列に配置するにはどうすればよいですか?

テキストファイルがあり、次のように配列を作成したいと思います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使用すると、その行から配列が作成されます。filebash

結果を配列自体で望むのか、それとも表示中の配列のテキスト表現で欲しいのかは明確ではありません。

得るために特別な要求された出力:

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コマンド 代替コマンドは、次の操作を行います。

  1. 一対の二重引用符で行を囲みます。
  2. 改行文字で二重引用符で囲まれた行を終了します。
  3. 結果行を標準出力として印刷します。

しかし、、標準出力として印刷する代わりに、コマンド全体の置換をコマンドの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

関連情報