bash:将变量的第一行分配给变量

bash:将变量的第一行分配给变量

我有一个多行变量,我只想要该变量中的第一行。以下脚本演示了该问题:

#!/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)ksh93zshbashmkshsh或最新版本的 FreeBSD

我敢打赌,您尝试使用sh而不是运行该脚本,bash并且您的sh脚本基于ashpdksh或尚不支持它的版本。yashksh88

如果您想让该代码兼容 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"

相关内容