在POSIX中对字符串中的字符进行迭代sh
#!/bin/sh
read -p "Enter sequence: " seq
for char in $seq; do
echo "$char"
done
我从标准输入读取“字符”序列。例如让它成为1234(),
在POSIX中对字符串中的字符进行迭代sh
我想改变它是这样的:
'1' '2' '3' '4' '(' ')' ','
我不想回应这个序列。我需要它有这个新的价值。
标准sh脚本中可能吗?
你可以用分割字符串sed
(1):
seq=`printf "%s\n" "$seq" | sed 's/./ &/g'`
'printf'%s \ n'“$ seq”'会比'echo $ seq'副作用小。如果您想要被吓到,请在[用于'echo的POSIX规范](http://pubs.opengroup.org/onlinepubs/009695399/utilities/echo.html)中搜索“implementation-defined”在应用使用部分。此外,'echo $ seq'上缺少引号意味着你用当前目录中的文件列表替换'*',带空格的标签(假设为默认IFS)等。 –
好的,谢谢你的提示。我更新了代码。 – clemens
由于命令替换会隐式删除尾随的换行符,因此我不太确定那里是否有任何优势。 –
我很惊讶,但是这是我所有的炮弹,并用奇怪的字符太(包括,例如,-
,(
,)
)工作(除了:
和):
iterate_over_chars()
{
#reset OPTIND in case this is going to be used multiple times
#(doable without local (which isn't POSIX) but local is nice and very portable)
local seq="$1" OPTIND=1
while getopts "$seq" opt "-$seq"; do
echo "$opt"
done
}
printf '%s\n' Enter sequence 2>/dev/null
read seq #read -p isn't exactly POSIX
iterate_over_chars "$seq"
的想法是与-
前缀词,然后把这个词作为一个选项组。
我使用_sed(1)_作为POSIX shell脚本来做到这一点,但对于调用它的性能开销感到不满,所以我搜索了一个纯shell解决方案,当我无法在我的系统上找到一个好的解决方案时拥有。我认为这种方法非常简单。感谢您发布这个答案。我真的认为这应该是公认的解决方案,特别是最近的编辑。 –
@EricPruitt感谢您的编辑。我以不同的方式整合了这个建议,因为我想保持答案的简短,并且我认为subshell打败了整个事情的目的(避免了过程产生的开销)。 – PSkocik
我不会扭转你的编辑,但我不同意subhells击败目的。在大多数系统中,使用子shell将导致在调用另一个_fork(2)_和_execve(2)_时调用_fork(2)_。在我正在处理的脚本中,我刚刚尝试了在子壳体中使用getopts与使用_sed(1)_。子shell版本的1,000次调用在3.7秒内运行。这仍然比_sed(1)_版本的14.3秒更好。执行时间。 –
嗯。在bash或ksh中有一个非常好的答案,它不涉及外部工具的开销,但是POSIX sh要求使得这更难。 –
如果用户输入空格会发生什么?如果'seq =“hello world”'怎么办? –
顺便说一句,在大多数情况下,用单引号包装不太可能是一种有用的行为。从命令替换中读取时,这些引号是字面的,而不是语法的,因此它们不会以任何方式阻止评估。 –