Это может быть лучшим подходом:
stty -F /dev/ttyUSB0 115200 raw -echo #CONFIGURE SERIAL PORT
exec 3</dev/ttyUSB0 #REDIRECT SERIAL OUTPUT TO FD 3
cat <&3 > /tmp/ttyDump.dat & #REDIRECT SERIAL OUTPUT TO FILE
PID=$! #SAVE PID TO KILL CAT
echo "R" > /dev/ttyUSB0 #SEND COMMAND STRING TO SERIAL PORT
sleep 0.2s #WAIT FOR RESPONSE
kill $PID #KILL CAT PROCESS
wait $PID 2>/dev/null #SUPRESS "Terminated" output
exec 3<&- #FREE FD 3
cat /tmp/ttyDump.dat #DUMP CAPTURED DATA
$ perl -e 'my @F=split //, shift;
for my $i (0..@F) { print $F[$i] x $F[++$i]};
print "\n"' A2B3C4
AABBBCCCC
Это разделяет ввод таким образом, что каждый отдельный символ становится элементом массива(@F
). Затем, используя оператор умножения строк Perl (x
), он печатает каждый элемент с четным -номером (, начиная с 0 ), число раз, равное следующему элементу с нечетным -номером.
или если вы хотите, чтобы он принимал ввод из стандартного ввода, а не из командной строки:
$ echo $'A2B3C4\nE5F2G7' | perl -ne 'my @F=split //;
for my $i (0..@F) { print $F[$i] x $F[++$i]};
print "\n"'
AABBBCCCC
EEEEEFFGGGGGGG
У обеих этих реализаций есть недостаток, заключающийся в том, что они допускают только строки из одной -цифры и подсчеты из одной -цифры.
Следующее снимает это ограничение:
$ echo A12B3CZ4 | perl -ne '
# insert a space between numbers and alphabetic characters.
s/([[:alpha:]])(\d)/$1 $2/g;
s/(\d)([[:alpha:]])/$1 $2/g;
# split on spaces
@F = split / /;
for my $i (0..@F) { print $F[$i] x $F[++$i]};
print "\n"'
AAAAAAAAAAAABBBCZCZCZCZ
Простая реализация оболочки:
#!/usr/bin/env bash
char=""
count=""
echo "$1" | while read -n1 -r c; do
if [ "$char" = "" ]
then
char="$c"
continue
fi
if [ "$count" = "" ]
then
count="$c"
for i in $(seq 1 "$count")
do
printf "%s" "$char"
done
char=""
count=""
continue
fi
done
printf "\n"
Пример:
$./transform.sh A2B3C4D0E1
AABBBCCCCE
Однако он не работает с числами больше 9. Нужно было бы реализовать некоторую большую логику, чтобы различать буквы и числа.
С помощью Perl вы можете сделать это так, как показано на рисунке:
echo a2b3c4 |
perl -pe 's/(\D)(\d+)/$1x$2/ge'
aabbbcccc