1

我正在尝试创建一个精美的欢迎消息,以便在终端打开时显示。我用这段代码在Java中完成了它:

public void slowPrint() {
    String message = "Welcome, " + System.getProperty("user.name");

    try {
        for(int i = 0; i < message.length(); i++) {
            System.out.print(message.charAt(i));
            Thread.sleep(50);
        }
    } catch(InterruptedException ex) {
        ex.printStackTrace();
    }
}

现在,我对 bash 还很陌生,但我设法编写了以下代码:

for i in W e l c o m e , $USER; do
    echo -ne $i
    sleep 0.05
done

echo !

这段代码有两个问题:

  1. 我不知道如何在逗号后打印一个纯空格,输出只是Welcome,simon!我怎样才能让它输出一个空格呢?
  2. 当然,它会$USER作为一个完整的单词打印。我希望它是一个字符一个字符,我该怎么做?
4

3 回答 3

4

您可以使用标准 for 循环来实现相同的效果:

MESSAGE="Welcome, $USER"
for (( i=0; i<${#MESSAGE}; i++ )); do
    echo -ne "${MESSAGE:$i:1}"
    sleep 0.05
done
echo !

${MESSAGE:$i:1}语法从字符串中的位置获取子字符串 1 i。将该部分括在引号中可确保同时打印空格和制表符之类的内容。

于 2013-03-30T10:37:57.783 回答
2

您可以很容易地指定空间;用引号括起来:

for i in W e l c o m e , ' ' ...

$USER可以通过多种方式拆分成单独的字符。我这样做的方式是老式但可靠的:

for i in W e l c o m e , ' ' $(sed 's/./& /g' <<< "$USER")

注意<<<操作保存了一个进程和一个管道;它重定向标准输入,sed因此它将给定的字符串作为输入行读取。

或者,如果您认为用户名可能包含任何空格或其他特殊字符:

for i in W e l c o m e , ' ' $(sed "s/./'&' /g" <<< "$USER")

(这不是万无一失的;该值USER="Tam O'Shanter"会引起一些悲伤,而对此的简单解决方案反而会遇到麻烦USER='Will "O'\''Wisp" Light'。...咕哝,咕哝,奥术咒语,...

    for i in W e l c o m e , ' ' $(sed "s/./'&' /g; s/'''/\\\\'/g" <<< "$USER")

除了在所有内容周围都用单引号呼应名称;发牢骚,发牢骚,...我想我刚刚弄清楚了为什么我不会同时这样做,...空格也会妨碍...我会使用简单的第一个版本并告诉人们不要在 的值中使用空格或特殊字符$USER。)

可能有 一些方法可以在不调用单独的过程的情况下做到这一点,例如sed;请参阅heuristicus答案。所以,就那样做吧。但请注意,它与此答案不完全相关的方式紧密相关- 您可以轻松地将符号(仅 -)替换为。bashbash<<<bashecho "$USER" | ...

于 2013-03-30T10:33:53.510 回答
0

完全 POSIXly 可移植,即没有那些讨厌的 bashisms,也没有用于 sed 的 fork:

#!/bin/sh

m="Welcome, $USER!"
while test ${#m} -gt 0; do
  r=${m#?}
  printf '%s ' "${m%%$r}"
  m=$r
  sleep 0.05
done
printf '\n'

请注意,几分之一秒的睡眠是不可移植的。

于 2013-03-30T11:24:07.857 回答