我有一个文本文件,我想用它创建一个数组,如下所示: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
换行符。这将从if usingarray
中的行创建数组。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
(并且根本不将行存储在 shell 数组中):
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
语句格式化输出的方式与 shell 代码示例中的方式几乎相同。 $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) )
为了每一个行中input_file
,从上到下,awk
命令替换中的命令执行以下操作:
- 用一对双引号将该行引起来。
- 用换行符结束双引号行。
- 将结果行打印到标准输出。
然而,不是打印到标准输出,而是使用命令的结果awk
来替换整个命令替换。替换是命令替换的结果。
接下来,对命令替换的结果应用分词。分词将不包括该IFS
字符但以该IFS
字符终止的任何字符序列识别为不同的“单词”。因此,在这种特殊情况下,“单词”是命令input_file
用一对双引号括起来的任何行(来自 )awk
。
由于命令替换是由最外面的一对括号括起来的()
,因此 的结果awk
被放置在这些括号之间,并且 shell 会处理整个括号,包括其间的所有替换标记(它们是并排放置的每个括起来的行)由一对双引号)作为数组。
笔记:
- 数组分配后,您可能希望将 shell 变量重置
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