Bash цикл, текущая итерация печати?

Скажем, у вас простой цикл

while read line
do
  printf "${line#*//}\n"
done < text.txt

Есть ли элегантный способ печати текущей итерации с выходом? Что-то вроде

0 The
1 quick
2 brown
3 fox

Я надеюсь избежать установки переменной и увеличения ее в каждом цикле.

Ответы

Ответ 1

Для этого вам нужно увеличить счетчик на каждой итерации (например, вы пытаетесь избежать).

count=0
while read -r line; do
   printf '%d %s\n' "$count" "${line*//}"
   (( count++ ))
done < test.txt

РЕДАКТИРОВАТЬ: после некоторых размышлений вы можете сделать это без счетчика, если у вас bash версия 4 или выше:

mapfile -t arr < test.txt
for i in "${!arr[@]}"; do
   printf '%d %s' "$i" "${arr[i]}"
done

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

Ответ 2

Вы не часто видите это, но вы можете иметь несколько команд в условии условия цикла while. Следующее по-прежнему требует явной переменной счетчика, но расположение может быть более подходящим или привлекательным для некоторых целей.

while ((i++)); read -r line
do
    echo "$i $line"
done < inputfile

Условие while выполняется тем, что возвращает последняя команда (read в этом случае).

Некоторые люди предпочитают включать do в одну строку. Вот как это выглядит:

while ((i++)); read -r line; do
    echo "$i $line"
done < inputfile

Ответ 3

n=0
cat test.txt | while read line; do
  printf "%7s %s\n" "$n" "${line#*//}"
  n=$((n+1))
done

Это тоже будет работать в оболочке Bourne.

Если вы действительно хотите избежать приращения переменной, вы можете вывести ее через grep или awk:

cat test.txt | while read line; do
  printf " %s\n" "${line#*//}"
done | grep -n .

или

awk '{sub(/.*\/\//, ""); print NR,$0}' test.txt

Ответ 4

Обновление: другие ответы, размещенные здесь, лучше, особенно те, что были @Graham и @DennisWilliamson.

Что-то очень похоже на это:

tr -s ' ' '\n' <test.txt | nl -ba

Вы можете добавить флаг -v0 в команду nl, если хотите индексировать с 0.