我有一个多行变量,我只想要该变量中的第一行。以下脚本演示了该问题:
#!/bin/bash
STRINGTEST="Onlygetthefirstline
butnotthesecond
orthethird"
echo " Take the first line and send to standard output:"
echo ${STRINGTEST%%$'\n'*}
# Output is as follows:
# Onlygetthefirstline
echo " Set the value of the variable to the first line of the variable:"
STRINGTEST=${STRINGTEST%%$'\n'*}
echo " Send the modified variable to standard output:"
echo $STRINGTEST
# Output is as follows:
# Onlygetthefirstline butnotthesecond orthethird
问题:为什么${STRINGTEST%%$'\n'*}
放在命令后面时返回第一行echo
,但放在赋值后面时用空格替换换行符?
答案1
可能不是最有效的,但只有一个班轮......
firstLine=`echo "${multiLineVariable}" | head -1`
答案2
也许还有其他方法可以存档您想做的事情,但这可行
#!/bin/bash
STRINGTEST="
Onlygetthefirstline
butnotthesecond
orthethird
"
STRINGTEST=(${STRINGTEST[@]})
echo "${STRINGTEST[0]}"
答案3
该代码适用于我在 2.05b 到 4.3 之间尝试过的所有 bash 版本。更有可能的是,您尝试使用不支持$'...'
引用形式的不同 shell 来运行该脚本。
该$'...'
语法还不是标准语法,仅由(其起源)、、、 的最新版本和sh
提供支持(截至 2015 年 5 月 22 日和 AFAIK)ksh93
zsh
bash
mksh
sh
或最新版本的 FreeBSD。
我敢打赌,您尝试使用sh
而不是运行该脚本,bash
并且您的sh
脚本基于ash
、pdksh
或尚不支持它的版本。yash
ksh88
如果您想让该代码兼容 POSIX 2008,您需要编写它:
STRINGTEST="Onlygetthefirstline
butnotthesecond
orthethird"
NL='
'
STRINGTEST=${STRINGTEST%%"$NL"*}
printf '%s\n' "$STRINGTEST"
然后,您可以使用任何符合 POSIX 标准的 shell bash
(例如您的sh
.
(请记住,在列表上下文中不加引号的变量在类似 Bourne 的 shell 中具有非常特殊的含义)。
答案4
使用 Bash 内置read
和此处字符串:
#!/usr/bin/env bash
STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"
IFS=$'\n' read -r STRINGTEST <<<"$STRINGTEST"
使用 POSIX 参数扩展:
#!/usr/bin/env sh
STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"
# Disables globing
set -f
# Field separator is newline only
IFS="
"
# No quotes, split lines as arguments because of IFS
set -- $STRINGTEST
# First argument is first line
STRINGTEST="$1"