Подтвердить что ты не робот

Увеличение переменной внутри цикла Bash

Я пытаюсь написать небольшой script, который будет считать записи в файле журнала, и я увеличиваю переменную (USCOUNTER), которую я пытаюсь использовать после завершения цикла.

Но в этот момент USCOUNTER выглядит как 0 вместо фактического значения. Любая идея, что я делаю неправильно? Спасибо!

FILE=$1

tail -n10 mylog > $FILE

USCOUNTER=0

cat $FILE | while read line; do
  country=$(echo "$line" | cut -d' ' -f1)
  if [ "US" = "$country" ]; then
        USCOUNTER=`expr $USCOUNTER + 1`
        echo "US counter $USCOUNTER"
  fi
done
echo "final $USCOUNTER"

Он выводит:

US counter 1
US counter 2
US counter 3
..
final 0
4b9b3361

Ответ 1

Вы используете USCOUNTER в подоболочке, поэтому переменная не отображается в основной оболочке.

Вместо cat FILE | while ... сделайте только a while ... done < $FILE. Таким образом, вы избегаете общей проблемы Я устанавливаю переменные в цикле, которые в конвейере. Почему они исчезают после завершения цикла? Или, почему я не могу передать данные для чтения?:

while read country _; do
  if [ "US" = "$country" ]; then
        USCOUNTER=$(expr $USCOUNTER + 1)
        echo "US counter $USCOUNTER"
  fi
done < "$FILE"

Примечание. Я также заменил выражение `` на $().

Я также заменил while read line; do country=$(echo "$line" | cut -d' ' -f1) на while read country _. Это позволяет вам сказать while read var1 var2 ... varN, где var1 содержит первое слово в строке, $var2 и т.д., Пока $varN не содержит оставшегося содержимого.

Ответ 2

while read -r country _; do
  if [[ $country = 'US' ]]; then
    ((USCOUNTER++))
    echo "US counter $USCOUNTER"
  fi
done < "$FILE"

Ответ 3

Вы получаете final 0, потому что ваш while loop выполняется в процессе sub (shell), и любые сделанные там изменения не отражаются в текущей (родительской) оболочке.

Исправить script:

while read -r country _; do
  if [ "US" = "$country" ]; then
        ((USCOUNTER++))
        echo "US counter $USCOUNTER"
  fi
done < "$FILE"

Ответ 4

минималистский

counter=0
((counter++))
echo $counter

Ответ 5

У меня была та же самая переменная $ count в цикле while, которая была потеряна.

Ответ @fedorqui (и несколько других) - это точные ответы на актуальный вопрос: проблема заключается в дополнительной оболочке.

Но это привело меня к другой проблеме: я не передавал содержимое файла... но выводил серию каналов и greps...

мой ошибочный пример кода:

count=0
cat /etc/hosts | head | while read line; do
  ((count++))
  echo $count $line
done
echo $count

и мое исправление благодаря помощи этой темы и процесса подстановки:

count=0
while IFS= read -r line; do
  ((count++))
  echo "$count $line"
done < <(cat /etc/hosts | head)
echo "$count"

Ответ 6

USCOUNTER=$(grep -c "^US " "$FILE")

Ответ 7

Приращение переменной может быть выполнено следующим образом:

  _my_counter=$[$_my_counter + 1]

Подсчет количества появления шаблона в столбце может быть выполнен с помощью grep

 grep -cE "^([^ ]* ){2}US"

-c count

([^ ]* ) Чтобы обнаружить колонию

{2} номер столбняка

US ваш шаблон

Ответ 8

Использование следующей команды 1 строки для изменения имени многих файлов в Linux с использованием специфики фразы:

find -type f -name '*.jpg' | rename 's/holiday/honeymoon/'

Для всех файлов с расширением ".jpg", если они содержат строку "праздник", замените ее на "медовый месяц". Например, эта команда переименует файл "ourholiday001.jpg" на "ourhoneymoon001.jpg".

В этом примере также показано, как использовать команду find для отправки списка файлов (-type f) с расширением .jpg(-name '*.jpg') для переименования через канал (|). rename затем считывает свой список файлов со стандартного ввода.