BASH разделить переменную на символы и распечатать пробел в цикле for
Я пытаюсь создать необычное приветственное сообщение, которое будет отображаться при открытии терминала. Я сделал это на 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 !
Есть две проблемы с этим кодом:
- Я понятия не имею, как напечатать пробел после запятой, вывод просто
Welcome,simon!
Как я могу сделать так, чтобы он выводил пробел? - Это, конечно же, печать
$USER
как целое слово. Я хотел бы, чтобы это было символ за персонажем, как я могу это сделать?
3 ответа
Вы можете использовать стандартный цикл 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
в строке. Заключение этой части в кавычки гарантирует, что такие вещи, как пробелы и табуляции также будут напечатаны.
Вы можете указать пространство достаточно легко; заключите его в кавычки:
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. Так что делай так. Но учтите, что он прочно привязан к bash
таким образом, что этот ответ не полностью связан с bash
- вы можете легко заменить <<<
обозначение (которое является bash
-только с echo "$USER" | ...
вместо.
Полностью POSIXly переносимый, то есть без этих надоедливых ударов и без разветвлений в sed:
#!/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'
Обратите внимание, что спать на доли секунды непереносимо.