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
Bash loop, print current iteration?
提问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 while
loop. 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 while
condition is satisfied by whatever the last command returns (read
in this case).
该while
条件是什么最后的命令返回(满足read
在这种情况下)。
Some people prefer to include the do
on 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 -v0
flag to the nl
command if you want indexing from 0.
如果您想从 0 开始索引,您可以-v0
向nl
命令添加一个标志。