Bash 循环,打印当前迭代?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10942825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:12:57  来源:igfitidea点击:

Bash loop, print current iteration?

bashloopswhile-loop

提问by Steven Penny

Say you have a simple loop

假设你有一个简单的循环

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

Is there an elegant way of printing the current iteration with the output? Something like

有没有一种优雅的方式用输出打印当前迭代?就像是

0 The
1 quick
2 brown
3 fox

I am hoping to avoid setting a variable and incrementing it on each loop.

我希望避免设置变量并在每个循环中增加它。

回答by jordanm

To do this, you would need to increment a counter on each iteration (like you are trying to avoid).

为此,您需要在每次迭代时增加一个计数器(就像您试图避免的那样)。

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

EDIT: After some more thought, you can do it without a counter if you have bash version 4 or higher:

编辑:经过深思熟虑后,如果您有 bash 版本 4 或更高版本,则可以在没有计数器的情况下执行此操作:

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

The mapfile builtin reads the entire contents of the file into the array. You can then iterate over the indices of the array, which will be the line numbers and access that element.

内置的 mapfile 将文件的全部内容读入数组。然后您可以迭代数组的索引,这些索引将是行号并访问该元素。

回答by Paused until further notice.

You don't often see it, but you can have multiple commands in the condition clause of a whileloop. The following still requires an explicit counter variable, but the arrangement may be more suitable or appealing for some uses.

您不会经常看到它,但是在while循环的条件子句中可以有多个命令。以下仍然需要一个明确的计数器变量,但这种安排可能更适合或对某些用途更有吸引力。

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

The whilecondition is satisfied by whatever the last command returns (readin this case).

while条件是什么最后的命令返回(满足read在这种情况下)。

Some people prefer to include the doon the same line. This is what that would look like:

有些人更喜欢将 包含do在同一行中。这就是它的样子:

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

回答by Graham

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

This will work in Bourne shell as well, of course.

当然,这也适用于 Bourne shell。

If you really want to avoid incrementing a variable, you can pipe the output through grep or awk:

如果你真的想避免增加一个变量,你可以通过 grep 或 awk 管道输出:

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

or

或者

awk '{sub(/.*\/\//, ""); print NR,
#!/bin/bash
for i in {0..10..2}; do 
   echo " $i times"
done
}' test.txt

回答by Sergio Perez

You can use a range to go through, it can be an array, a string, a input line or a list.

您可以使用范围来遍历,它可以是数组、字符串、输入行或列表。

In this example, i use a list of numbers [0..10] is used with an increment of 2, as well.

在这个例子中,我使用了一个数字列表 [0..10] 也使用了 2 的增量。

 0 times
 2 times
 4 times
 6 times
 8 times
 10 times

The output is:

输出是:

#!/bin/bash 

COUNTER=0
line="this is a sample input line"

for word in $line; do        
    echo "This i a word number $COUNTER: $word"
    COUNTER=$((COUNTER+1))
done

To print the index regardless of the loop range, you have to use a variable "COUNTER=0" and increase it in each iteration "COUNTER+1".

要在不考虑循环范围的情况下打印索引,您必须使用变量“COUNTER=0”并在每次迭代“COUNTER+1”中增加它。

my solution prints each iteration, the FOR traverses an inputline and increments by one each iteration, also shows each of words in the inputline:

我的解决方案打印每次迭代, FOR 遍历输入行并每次迭代递增 1,还显示输入行中的每个单词:

This i a word number 0: this
This i a word number 1: is
This i a word number 2: a
This i a word number 3: sample
This i a word number 4: input
This i a word number 5: line

The output is:

输出是:

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

to see more about loops: enter link description here

要查看有关循环的更多信息:在此处输入链接描述

to test your scripts: enter link description here

测试您的脚本:在此处输入链接描述

回答by thb

Update:Other answers posted here are better, especially those of @Graham and @DennisWilliamson.

更新:此处发布的其他答案更好,尤其是@Graham 和@DennisWilliamson 的答案。

Something very like this should suit:

非常像这样的东西应该适合:

##代码##

You can add a -v0flag to the nlcommand if you want indexing from 0.

如果您想从 0 开始索引,您可以-v0nl命令添加一个标志。