我正在努力编写一个 bash 脚本,其中包含一个具有长字符串值的变量。当我将字符串分成多行时,它会抛出错误。如何将字符串分成多行并分配给变量?
答案1
将长字符串分配为数组中的多个子字符串可以使代码更具美观性:
#!/bin/bash
text=(
'Contrary to popular'
'belief, Lorem Ipsum'
'is not simply'
'random text. It has'
'roots in a piece'
'of classical Latin'
'literature from 45'
'BC, making it over'
'2000 years old.'
)
# output one line per string in the array:
printf '%s\n' "${text[@]}"
# output all strings on a single line, delimited by space (first
# character of $IFS), and let "fmt" format it to 45 characters per line
printf '%s\n' "${text[*]}" | fmt -w 45
做相反的事情,即取一长行,将其分成多行,并将它们读入数组变量:
$ cat file
Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old.
我们fmt
在这里使用将行分成最多 30 个字符长的较短行,然后readarray
在bash
shell 中将这些行读入名为的数组中text
:
$ readarray -t text < <(fmt -w 30 file)
现在我们可以访问这组行或每个单独的行:
$ printf '%s\n' "${text[@]}"
Contrary to popular belief,
Lorem Ipsum is not simply
random text. It has roots in a
piece of classical Latin
literature from 45 BC, making
it over 2000 years old.
$ printf '%s\n' "${text[3]}"
piece of classical Latin
(请注意,数组是从零开始的bash
。)
答案2
一个建议:
x='Lorem ipsum dolor sit amet, consectetur '\
'adipiscing elit, sed do eiusmod tempor '\
'incididunt ut labore et dolore magna aliqua.'
其结果是预期的:
$ printf '%s\n' "$x"
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
答案3
如果要点是在 shell 变量中存储很长的行,但要让代码这样做不超过某个固定宽度,假设有一个类似 Bourne 的 shell,您可以这样做:
string="Rerum inventore nemo neque reiciendis ullam. Volupta\
te amet eveniet corporis nostrum. Laboriosam id sapiente atq\
ue non excepturi. Dolorem alias sed et voluptatem est unde s\
ed atque. Itaque ut molestias alias dolor eos doloremque exp\
licabo. Quas dolorum sint sit dicta nemo qui."
在双引号内(与单引号相反),反斜杠换行符仍被视为行延续)。请注意,双引号内的 , "
, $
, `
(\
有时!
) 仍然很特殊,需要转义。
避免担心引用的方法是编写:
string=$(<<'EOF' tr -d '\n'
Rerum inventore nemo neque reiciendis ullam. Vo
luptate amet eveniet corporis nostrum. Laborios
am id sapiente atque non excepturi. Dolorem ali
as sed et voluptatem est unde sed atque. Itaque
ut molestias alias dolor eos doloremque explic
abo. Quas dolorum sint sit dicta nemo qui. 'And
'#\`"$% whatever.
EOF
)
当<<
分隔符被引用时,即使是部分引用,此处文档的正文中也不会进行扩展。在这里,我们捕获其输出,tr
并将其输入到此处文档,并从中d
删除n
ewline 字符。您可以使用类似的方法来添加一些缩进:
string=$(<<'EOF' cut -b3- | tr -d '\n'
Rerum inventore nemo neque reiciendis ullam. Vo
luptate amet eveniet corporis nostrum. Laborios
am id sapiente atque non excepturi. Dolorem ali
as sed et voluptatem est unde sed atque. Itaque
ut molestias alias dolor eos doloremque explic
abo. Quas dolorum sint sit dicta nemo qui. 'And
'#\`"$% whatever.
EOF
)
答案4
我会在命令行提示符下这样写。当然,它可以更压缩,但为了清楚起见:
~$ text='You can do this, but the newlines will be embedded in the variable, so it won’t be a single line'
~$ array=$(echo $text | cut -d' ' -f 1-)
~$ for x in ${array[@]}; do echo $x ; done
这是单行:
~$ echo $text | tr ' ' '\n'
输出:
You
can
do
this,
but
the
newlines
will
be
embedded
in
the
variable,
so
it
won’t
be
a
single
line
或者,对于排序输出:
~$ echo $text | tr ' ' '\n' | sort
输出:
a
be
be
but
can
do
embedded
in
it
line
newlines
single
so
the
the
this,
variable,
will
won’t
You