在Shell脚本的for循环中逐行遍历文本文件

时间:2020-09-03 19:40:09

标签: bash shell loops

我有一个名为locations.txt的txt文件:

location-1a
location-2c
location-3d
location-4
location-5a
...

我希望在for循环中遍历locations.txt文件,每个位置应用于5个节点,然后应使用下一个位置。因此,例如,我要运行以下命令,

server create --location location-1a node-1
server create --location location-1a node-2
server create --location location-1a node-3
server create --location location-1a node-4
server create --location location-1a node-5
server create --location location-2c node-6

.....

到目前为止,我只有以下名为script.sh的脚本,它带有cli的参数。我无法按照自己的意愿更改位置。

mapfile -t locationArr < ~/Documents/files/locations.txt
serverCounter=1
locationCounter=1
counter=1

counter=1
for (( i = 1; i <= $1; i++ ))
do
 server create --location $locationArr[$locationCounter] node-$i
 counter=$((counter+1))
 if [ $counter == 5 ]
 then
  counter=1
  locationCounter=$((locationCounter+1))
done

我想要类似的东西

if counter == 5:
 counter=0
 nextline 

例如,如果我运行script.sh 11,我想要以下结果,

server create --location location-1a node-1
server create --location location-1a node-2
server create --location location-1a node-3
server create --location location-1a node-4
server create --location location-1a node-5
server create --location location-2c node-6
server create --location location-2c node-7
server create --location location-2c node-8
server create --location location-2c node-9
server create --location location-2c node-10
server create --location location-3d node-11

如何在for循环中遍历location.txt文件?我应该将文本文件转换为某种列表变量吗?

3 个答案:

答案 0 :(得分:2)

这是我的尝试

counter=1
while IFS= read -r line
do
    for (( i=1; i <= 5 && $counter <= $1; i++ ))
    do
     server create --location $line node-$counter
     counter=$((counter+1))
    done 
done < ~/Documents/files/locations.txt

输出为11:

server create --location location-1a node-1
server create --location location-1a node-2
server create --location location-1a node-3
server create --location location-1a node-4
server create --location location-1a node-5
server create --location location-2c node-6
server create --location location-2c node-7
server create --location location-2c node-8
server create --location location-2c node-9
server create --location location-2c node-10
server create --location location-3d node-11

答案 1 :(得分:1)

概述:

  • 用于从locations.txt读取位置的外循环
  • 用于为给定位置生成最多5个节点的内部循环
  • 每次生成节点都会增加一个计数
  • 如果计数器>输入“ max”,则跳出循环

上述的一种实现方式:

max=${1}
curr=1

while read -r location
do
    for i in {1..5}
    do
        echo "server create --location ${location} node-${curr}"
        curr=$((curr+1))
        [ ${curr} -gt ${max} ] && break 2
    done
done < locations.txt

使用max=${1}=11进行测试:

server create --location location-1a node-1
server create --location location-1a node-2
server create --location location-1a node-3
server create --location location-1a node-4
server create --location location-1a node-5
server create --location location-2c node-6
server create --location location-2c node-7
server create --location location-2c node-8
server create --location location-2c node-9
server create --location location-2c node-10
server create --location location-3d node-11

OP可以为max是大于0的整数添加附加检查。

答案 2 :(得分:1)

完成单循环,没有Bashism POSIX语法:

#!/usr/bin/env sh

i=0
while [ $i -lt "$1" ] && {
  [ $((i % 5)) -ne 0 ] || IFS= read -r line || [ "$line" ]
}; do
  server create --location "$line" "node-$((i = i + 1))"
done <locations.txt