多行变量删除换行符 - 鱼
Multi-line variables remove new line character - Fish
当我在 fish 中将任何多行文本设置为变量时,它会删除换行符并将其替换为 space,我该如何阻止它这样做?最小的完整示例:
~ ) set lines (cat .lorem); set start 2; set end 4;
~ ) cat .lorem
once upon a midnight dreary while i pondered weak and weary
over many a quaint and curious volume of forgotten lore
while i nodded nearly napping suddenly there came a tapping
as of some one gently rapping rapping at my chamber door
tis some visiter i muttered tapping at my chamber door
~ ) cat .lorem | sed -ne $start\,{$end}p\;{$end}q # Should print lines 2..4
over many a quaint and curious volume of forgotten lore
while i nodded nearly napping suddenly there came a tapping
as of some one gently rapping rapping at my chamber door
~ ) echo $lines
once upon a midnight dreary while i pondered weak and weary over many a quaint and curious volume of forgotten lore while i nodded nearly napping suddenly there came a tapping as of some one gently rapping rapping at my chamber door tis some visiter i muttered tapping at my chamber door
不只是删除换行符,而是拆分它们。
您的变量 $lines 现在是一个列表,每一行都是该列表中的一个元素。
见
set lines (cat .lorem)
for line in $lines
echo $line
end
echo $lines[2]
printf "%s\n" $lines[2..4]
fish 在换行符上拆分命令替换。这意味着 $lines
是一个列表。您可以阅读更多 about lists here.
当您将列表传递给命令时,列表中的每个条目都会成为一个单独的参数。 echo
space - 分隔其参数。这解释了您所看到的行为。
请注意,其他 shell 在这里做同样的事情。例如,在 bash:
lines=$(cat .lorem)
echo $lines
如果要防止分裂,可以暂时将IFS设置为空:
begin
set -l IFS
set lines (cat .lorem)
end
echo $lines
现在 $lines
将包含换行符。
正如faho所说,read
也可以用,而且稍微短一点:
read -z lines < ~/.lorem
echo $lines
但请考虑按换行符拆分是否真的是您想要的。正如 faho 所暗示的,您的 sed
脚本可以替换为数组切片:
set lines (cat .lorem)
echo $lines[2..4] # prints lines 2 through 4
通过管道传输到 string split0
。
set lines (echo -e 'hi\nthere')
set -S lines
# $lines: set in global scope, unexported, with 2 elements
# $lines[1]: length=2 value=|hi|
# $lines[2]: length=5 value=|there|
set lines (echo -e 'hi\nthere' | string split0)
set -S lines
# $lines: set in global scope, unexported, with 1 elements
# $lines[1]: length=9 value=|hi\nthere\n|
这在 the document 中注明:
If the output is piped to string split or string split0 as the last step, those splits are used as they appear instead of splitting lines.
从 fish 3.4 开始,我们可以使用 "$(innercommand)"
语法。
set lines "$(echo -e 'hi\nthere')"
当我在 fish 中将任何多行文本设置为变量时,它会删除换行符并将其替换为 space,我该如何阻止它这样做?最小的完整示例:
~ ) set lines (cat .lorem); set start 2; set end 4;
~ ) cat .lorem
once upon a midnight dreary while i pondered weak and weary
over many a quaint and curious volume of forgotten lore
while i nodded nearly napping suddenly there came a tapping
as of some one gently rapping rapping at my chamber door
tis some visiter i muttered tapping at my chamber door
~ ) cat .lorem | sed -ne $start\,{$end}p\;{$end}q # Should print lines 2..4
over many a quaint and curious volume of forgotten lore
while i nodded nearly napping suddenly there came a tapping
as of some one gently rapping rapping at my chamber door
~ ) echo $lines
once upon a midnight dreary while i pondered weak and weary over many a quaint and curious volume of forgotten lore while i nodded nearly napping suddenly there came a tapping as of some one gently rapping rapping at my chamber door tis some visiter i muttered tapping at my chamber door
不只是删除换行符,而是拆分它们。
您的变量 $lines 现在是一个列表,每一行都是该列表中的一个元素。
见
set lines (cat .lorem)
for line in $lines
echo $line
end
echo $lines[2]
printf "%s\n" $lines[2..4]
fish 在换行符上拆分命令替换。这意味着 $lines
是一个列表。您可以阅读更多 about lists here.
当您将列表传递给命令时,列表中的每个条目都会成为一个单独的参数。 echo
space - 分隔其参数。这解释了您所看到的行为。
请注意,其他 shell 在这里做同样的事情。例如,在 bash:
lines=$(cat .lorem)
echo $lines
如果要防止分裂,可以暂时将IFS设置为空:
begin
set -l IFS
set lines (cat .lorem)
end
echo $lines
现在 $lines
将包含换行符。
正如faho所说,read
也可以用,而且稍微短一点:
read -z lines < ~/.lorem
echo $lines
但请考虑按换行符拆分是否真的是您想要的。正如 faho 所暗示的,您的 sed
脚本可以替换为数组切片:
set lines (cat .lorem)
echo $lines[2..4] # prints lines 2 through 4
通过管道传输到 string split0
。
set lines (echo -e 'hi\nthere')
set -S lines
# $lines: set in global scope, unexported, with 2 elements
# $lines[1]: length=2 value=|hi|
# $lines[2]: length=5 value=|there|
set lines (echo -e 'hi\nthere' | string split0)
set -S lines
# $lines: set in global scope, unexported, with 1 elements
# $lines[1]: length=9 value=|hi\nthere\n|
这在 the document 中注明:
If the output is piped to string split or string split0 as the last step, those splits are used as they appear instead of splitting lines.
从 fish 3.4 开始,我们可以使用 "$(innercommand)"
语法。
set lines "$(echo -e 'hi\nthere')"