Я пытаюсь изучить сценарии оболочки bash и awk, и я написал простой код, который перебирает заданные аргументы, и если параметры содержат цифры, я печатаю только цифры.
Затем, используя AWK, я добавлял их один за другим и выводил сумму. И я застрял здесь. Это мой код:
#!/bin/bash
for user in "$@"
do
echo "$user"
if [[ $user =~ [0-9]+ ]]; then
usersDigits=$(echo $user | tr -dc '0-9')
echo "$usersDigits"
echo "has digits"
echo $(awk '{ sum+=$usersDigits } END { print sum }')
else
echo "doesn't have digits"
fi
done
Что я делаю неправильно?
андра – Ты пытаешься встроить руль своей машины внутрь своего телевизора. Точно так же, как у вас может быть телевизор в машине, вы можете иметь сценарий awk внутри сценария оболочки, но это не означает, что awk является оболочкой. Это два совершенно разных инструмента со своими языками/сферой применения/синтаксисом/семантикой. См. cfajohnson.com/shell/cus-faq-2.html#Q24, как использовать значение переменных оболочки внутри awk-скриптов. @JBone - нет, есть несколько проблем с предложенной вами 1 строкой кода.
1) Ваш код застрянет, так как awk ожидает входной файл или данные из STDIN. Вы можете добавить /dev/null, если не хотите обрабатывать какие-либо файлы. Вы можете прочитать этот ТАК вопрос, чтобы понять больше об этом.
2) Даже если вы исправите это, сумма не будет рассчитана, так как сумма переменной будет сбрасываться в каждом цикле, так как awk считает ее новой переменной.
Обратите внимание на разницу в выводе в следующих 3 попытках:
for user in "$@"
do
printf "\nUser: $user \n"
if [[ $user =~ [0-9]+ ]]; then
usersDigits=$(echo $user | tr -dc '0-9')
echo "$usersDigits"
echo "has digits"
printf "First Try : " && awk 'END {print $usersDigits}' < /dev/null
printf "Second Try : " && awk 'END {print "$usersDigits"}' < /dev/null
printf "Third Try : " && awk -v dg = "$usersDigits" 'BEGIN {printf "Digits= " dg; sum+=dg; print " Sum= " sum}'
else
echo "doesn't have digits"
fi
done
Вывод для «test.ksh acs acs005 acs007»:
User: acs
doesn't have digits
User: acs005
005
has digits
First Try :
Second Try : $usersDigits
Third Try : Digits= 005 Sum= 5
User: acs007
007
has digits
First Try :
Second Try : $usersDigits
Third Try : Digits= 007 Sum= 7
В первых двух userDigits не определен внутри awk. Я надеюсь, что это помогает.
Обновлять: Скрипт с логикой для вычисления суммы цифр
for user in "$@"
do
printf "\nUser: $user \n"
if [[ $user =~ [0-9]+ ]]; then
usersDigits=$(echo $user | tr -dc '0-9')
echo "$usersDigits"
echo "has digits"
printf "Sum of Digits:" && awk -v dg = "$usersDigits" 'BEGIN {while( dg+0 > 0) {digit=dg%10; DigSum+=int(digit); dg=int(dg/10);}; print DigSum }' < /dev/null
еще echo "нет цифр" фи Готово
Пример вывода:
./test.ksh acs acs005 acs007 acs123 345
User: acs
doesn't have digits
User: acs005
005
has digits
Sum of Digits:5
User: acs007
007
has digits
Sum of Digits:7
User: acs123
123
has digits
Sum of Digits:6
User: 345
345
has digits
Sum of Digits:12
спасибо @ acs005, но это все еще не добавляет числа. Если я поставлю 123 в качестве аргумента, он отобразит то же самое вместо 6. есть идеи, почему?
Потому что логики добавления отдельных цифр нет в коде. Фрагмент кода, который вы показали, просто анализирует входную строку и проверяет, есть ли в ней какие-либо числа. Далее это число не разбивается на отдельные цифры, а складывается для вычисления общей суммы.
Я добавил модифицированный скрипт для вычисления суммы цифр. Если вы считаете это полезным, отметьте ответ соответствующим образом.
вы можете назначить переменные bash с помощью
-v
, а затем использовать это, как здесьecho $(awk -v awkVar= $usersDigits '{ sum+=$awkVar } END { print sum }')
.. попробуйте это