我想/bin/sh
在 BSD 平台上的POSIX shell ( ) 中处理多行字符串并逐行迭代它。Bash 不包含在基本的 BSD 发行版中,并且拥有 GPL 许可证——所以我试图让它普遍使用/bin/sh
。
我找到了一个使用管道的解决方案,但是在常规/bin/sh
shell 中,这些是在单独的进程中处理的,这意味着以下内容不起作用:
MULTILINE="`cat ${SOMEFILE}`"
SOMEVAR="original value"
echo "${MULTILINE}" | while IFS= read -r SINGLELINE
do
SOMEVAR="updated value"
echo "this is a single line: ${SINGLELINE}"
echo "SOMEVAR is now: ${SOMEVAR}"
done
echo "Final SOMEVAR is unchanged: ${SOMEVAR}"
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,它完成了我想要的,除了${SOMEVAR}
在 while 循环之外无法访问对诸如此类的变量的更改这一事实。
我的问题:如何在没有此限制的情况下完成上述操作?请注意,许多解决方案需要 Bash,而我使用的是标准 POSIX-shell /bin/sh
。
您可以使用此处的文档:
while IFS= read -r SINGLELINE
do
SOMEVAR="updated value"
printf '%s\n' "this is a single line: ${SINGLELINE}"
printf '%s\n' "SOMEVAR is now: ${SOMEVAR}"
done << EOF
$MULTILINE
EOF
printf '%s\n' "Final SOMEVAL is still $SOMEVAR"
Run Code Online (Sandbox Code Playgroud)
根据sh
实现,here-documents 要么被实现为一个已删除的临时文件,其中 shell 已经存储了变量的扩展,然后是换行符,或者是一个管道,shell 将变量的扩展提供给它,然后是换行符。但在任何一种情况下,除了原始 Bourne shell(现在不再使用的 shell,并且不是 POSIX 兼容的 shell),被重定向的命令不会在子 shell 中运行(如 POSIX 要求)。
或者你可以使用 split+glob:
IFS='
' # split on newline only
set -o noglob
for SINGLELINE in $MULTILINE
do
SOMEVAR="updated value"
printf '%s\n' "this is a single line: ${SINGLELINE}"
printf '%s\n' "SOMEVAR is now: ${SOMEVAR}"
done
printf '%s\n' "Final SOMEVAL is still $SOMEVAR"
Run Code Online (Sandbox Code Playgroud)
但要注意它会跳过空行。
归档时间: |
|
查看次数: |
2933 次 |
最近记录: |