简体   繁体   English

要不断循环使用for in shell脚本

[英]To Continuously loop using for in shell scripting

for m in $count
  do
        `cat $op ${arr[$m]} > $op1`
        `rm -f $op`
        `touch $op`
        `cat $op1 ${arr[$m+1]} > $op`
        if [ $m ge $count ]; then
        `rm -f $op1`
        `touch $op1`
        fi
        m=$((m+1))
  done

I wanted to continuously loop from the start count 2 till the end count 10 . 我想从开始计数2到结束计数10连续循环播放。 The $count=10 here. $ count = 10。 But the above piece of code executes the for loop only once. 但是上面的代码只执行一次for循环。

Rainy sunday - having much free time - long answer ;) 雨天-有很多空闲时间-)

Many issues with your script, some recommended solutions. 您的脚本有很多问题,一些推荐的解决方案。 Because you used the construction m=$((m+1)) - will be using bash as "shell". 因为您使用了构造m=$((m+1)) -将bash用作“ shell”。 (Consider adding the bash tag) (考虑添加bash标签)

For the cycle - several possibilities 对于循环-几种可能性

count=10
m=2                           #start with 2
while (( $m <= $count ))      #while m is less or equal to 10
do                            #do
        echo $m               #this action
        let m++               #increment m (add one to m)
done                          #end of while

or, if the count is a constant (not a variable), you can write 或者,如果计数是一个常数(不是变量),则可以编写

for m in {2..10}    #REMEMBER, will not works with a variables, like  {2..$count}
do
    echo "$m"
done

another variant - using the seq ( man seq ) command for counting 另一个变体-使用seqman seq )命令进行计数

for m in $(seq 2 ${count:=10})  # ${count:=10} - defaults the $count to 10 if it is undefined
do
    echo $m
done

or C-like for loop 或类似C的for循环

let count=10
for ((m=2; m<=count; m++))
do
        echo $m
done

All 4 loops produces: 所有4个循环都会产生:

2
3
4
5
6
7
8
9
10

so, having a right cycle now. 因此,现在有一个正确的周期。 Now add your specific actions. 现在添加您的特定操作。

The: 的:

rm -f $op
touch $op

can be replaced by one command 可以用一个命令代替

echo -n > $op  #echo nothing and write the "nothing" into the file

it is faster, because the echo is an bash builtin (doesn't start two external commands) 它更快,因为echo内置bash (不启动两个外部命令)

So your actions could looks like 所以你的动作看起来像

cat $op ${arr[$m]} > $op1
echo -n > $op
cat $op1 ${arr[$m+1]} > $op

in this case, the echo is useless, because the second cat will write its output to the $op anyway (and before write shortens the file to zero size), so this result is identical with the above 在这种情况下, echo是没有用的,因为第二cat将无论如何都将其输出写入$ op(并且在写入之前将文件缩短为零大小),因此此结果与上面的结果相同

cat $op ${arr[$m]} > $op1
cat $op1 ${arr[$m+1]} > $op      

Those two cat commands can be shorted to one, using bash's >> append to file redirection 使用bash的>>追加到文件重定向,可以将这两个cat命令简化为一个

cat ${arr[$m]} ${arr[m+1]} >> $op

The whole script could look like the next 整个脚本看起来像下一个

#making a testing environment

for f in $(seq 12)               #create 12 files opdata-N 
do
    arr[$f]="opdata-$f"          #store the filenames in the array "arr"
    echo "data-$f" > ${arr[$f]}  #each file contains one line "data-N"
done
#echo ${arr[@]}

#setting the $op and $op1 filenames
#consider choosing more descriptive variable names
op="file_op"
#op1="file_op1"   #not needed

#add some initial (old) value to $op
echo "initial value" > $op
#end of creating the testing environment

#the script
count=10
for m in $(seq 2 $count)
do
    cat ${arr[$m]} ${arr[m+1]} >> $op   
done

at the end, file $op will contain: 最后,文件$op将包含:

initial value
data-2
data-3
data-3
data-4
data-4
data-5
data-5
data-6
data-6
data-7
data-7
data-8
data-8
data-9
data-9
data-10
data-10
data-11

BTW, are you sure about the result? 顺便说一句,你确定结果吗? Because if only want add file-2 .. file-10 to the end of $op (without duplicating entries), you can simple write: 因为如果只想在$op的末尾添加file-2 .. file-10 (不重复条目),则可以简单地编写:

cat file-{2..10} >> $op    #the '>>' adds to the end of file...

or by using your array: 或使用您的数组:

startpos=2
count=10
cat ${arr[@]:$startpos:$count} >> $op   

Ufff.. ;) Ufff ..;)

Ps: usually it is good practice to enclose variables in double quotes like "$filename" - in the above examples for better readability I omitted them. 附:通常,将变量用双引号引起来是一个好习惯,例如"$filename" -为了更好的可读性,在上述示例中,我省略了它们。

Any loop needs a "condition to keep looping". 任何循环都需要“保持循环的条件”。 When you use a 当您使用

for m in count

type of loop, the condition is "if there are more elements in the collection count , pick the next one and keep going". 循环类型,条件是“如果集合count有更多元素,请选择下一个并继续”。 This doesn't seem to be what you want. 这似乎不是您想要的。 You are looking for the bash equivalent of 您正在寻找相当于的bash

for(m = 0; m < 10; m++)

I think. 我认为。 The best way to do this is - with exactly that kind of loop (but note - an extra pair of parentheses, and a semicolon): 最好的方法是-完全使用这种循环(但请注意-额外的一对括号和分号):

#!/bin/bash
# Display message 5 times
for ((i = 0 ; i < 5 ; i++)); do
  echo "Welcome $i times."
done

see nix craft for original 参见nix工艺原创

I think you can extend this to your situation… if I understood your question correctly you need something like this: 我认为您可以将此扩展到您的情况……如果我正确理解了您的问题,则需要这样的事情:

for ((m = 2; m <= 10; m++))
  do
    cat $op ${arr[$m]} > $op1
    rm -f $op
    touch $op
    cat $op1 ${arr[$m+1]} > $op
    if [ $m ge $count ]; then
      rm -f $op1
      touch $op1
    fi
  done

Use a while loop instead. 请改用while循环。

The for loop is when you have multiple objects to iterate against. for循环是当您有多个要迭代的对象时。 You have only one, ie $count. 您只有一个,即$ count。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM