BASH,多个数组和一个循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2745139/
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, multiple arrays and a loop
提问by S1syphus
At work, we have 7 or 8 hardrives we dispatch over the country, each have unique labels which are not sequential.
在工作中,我们有 7 或 8 个 hardrives 派往全国各地,每个都有独特的标签,并且不连续。
Ideally drives are plugged in our desktop, then gets folders from the server that correspond to the drive name.
理想情况下,驱动器插入我们的桌面,然后从服务器获取与驱动器名称相对应的文件夹。
Sometimes, only one hard drive gets plugged in sometimes multiples, possibly in the future more will be added.
有时,只插入一个硬盘驱动器有时会插入多个,将来可能会添加更多。
Each is mounted to /Volumes/ and its identifier; so for example /Volumes/f00, where f00 is the identifier.
每个都挂载到 /Volumes/ 及其标识符;例如 /Volumes/f00,其中 f00 是标识符。
What I want to happen, scan volumes see if any any of the drives are plugged in, then check the server to see if the folder exists, if it does copy folder and recursive folders.
我想要发生的是,扫描卷查看是否插入了任何驱动器,然后检查服务器以查看该文件夹是否存在,是否确实复制了文件夹和递归文件夹。
Here is what I have so far, it checks if the drive exists in Volumes:
这是我到目前为止所拥有的,它检查驱动器是否存在于 Volumes 中:
#!/bin/sh
#Declare drives in the array
ARRAY=( foo bar long )
#Get the drives from the array
DRIVES=${#ARRAY[@]}
#Define base dir to check
BaseDir="/Volumes"
#Define shared server fold on local mount points
#I plan to use AFP eventually, but for the sake of ease
#using a local mount.
ServerMount="BigBlue"
#Define folder name for where files are to come from
Dispatch="File-Dispatch"
dir="$BaseDir/${ARRAY[${i}]}"
#Loop through each item in the array and check if exists on /Volumes
for (( i=0;i<$DRIVES;i++));
do
dir="$BaseDir/${ARRAY[${i}]}"
if [ -d "$dir" ]; then
echo "$dir exists, you win."
else
echo "$dir is not attached."
fi
done
What I can't figure out how to do, is how to check the volumes for the server while looping through the harddrive mount points.
我不知道该怎么做,是如何在遍历硬盘驱动器安装点时检查服务器的卷。
So I could do something like:
所以我可以做这样的事情:
#!/bin/sh
#Declare drives, and folder location in arrays
ARRAY=( foo bar long )
#Get the drives from the array
DRIVES=${#ARRAY[@]}
#Define base dir to check
BaseDir="/Volumes"
#Define shared server fold on local mount points
ServerMount="BigBlue
#Define folder name for where files are to come from
Dispatch="File-Dispatch"
dir="$BaseDir/${ARRAY[${i}]}"
#List the contents from server directory into array
ARRAY1=($(ls ""$BaseDir"/"$ServerMount"/"$Dispatch""))
SERVERFOLDER=${#ARRAY1[@]}
echo ${list[@]}
for (( i=0;i<$DRIVES;i++)); (( i=0;i<$SERVERFOLDER;i++));
do
dir="$BaseDir/${ARRAY[${i}]}"
ser="${ARRAY1[${i}]}"
if [ "$dir" =~ "$sir" ]; then
cp "$sir" "$dir"
else
echo "$dir is not attached."
fi
done
I know, that is pretty wrong... well very, but I hope it gives you the idea of what I am trying to achieve.
我知道,那是非常错误的……非常错误,但我希望它能让您了解我正在努力实现的目标。
Any ideas or suggestions?
有什么想法或建议吗?
采纳答案by Paused until further notice.
Some notes:
一些注意事项:
- You're using variables before you define them (I see that you set this variable a second time in a more appropriate place) and those quotes are unnecessary:
ARRAY1=($(ls "$BaseDir/$ServerMount/$Dispatch")) - Missing closing quote:
ServerMount="BigBlue" - Using curly braces when they're not necessary hinders readability (you could also omit the dollar sign for array subscripts):
dir="$BaseDir/${ARRAY[i]}" - This array isn't defined:
echo ${list[@]} - Huh? I think you may want nested for loops and you have to use different variables. Instead of:
for (( i=0;i<$DRIVES;i++)); (( i=0;i<$SERVERFOLDER;i++));
try:
- 您在定义变量之前使用了它们(我看到您在更合适的地方再次设置了这个变量)并且这些引号是不必要的:
ARRAY1=($(ls "$BaseDir/$ServerMount/$Dispatch")) - 缺少结束语:
ServerMount="BigBlue" - 在不必要时使用花括号会影响可读性(您也可以省略数组下标的美元符号):
dir="$BaseDir/${ARRAY[i]}" - 此数组未定义:
echo ${list[@]} - 嗯?我认为您可能需要嵌套 for 循环,并且必须使用不同的变量。而不是:
for (( i=0;i<$DRIVES;i++)); (( i=0;i<$SERVERFOLDER;i++));
尝试:
for (( i= ...
do
for (( j= ...
do
dir="$BaseDir/${ARRAY[i]}"
ser="${ARRAY1[j]}"
- You should be aware that if the filenames or directory names have spaces in them, iterating over an array will fail. The alternative is to pipe
findinto awhile...readloop. - Here you call it "ser" and then you call it "sir":
ser="${ARRAY1[i]}"
- 您应该知道,如果文件名或目录名中包含空格,则遍历数组将失败。另一种方法是通过管道
find进入while...read循环。 - 在这里你称它为“ser”,然后你称它为“sir”:
ser="${ARRAY1[i]}"
回答by Kilian Foth
You appear to be confused about nested forloops, quite independent of arrays. The first trick is not to use the same index variable for both loops, and the second is to interleave the keywords and the enumerations properly, like this:
您似乎对嵌套for循环感到困惑,完全独立于数组。第一个技巧是不要对两个循环使用相同的索引变量,第二个技巧是正确地交错关键字和枚举,如下所示:
for x in a b c; do
for y in 1 2 3; do
echo $x$y
done
done
This prints:
这打印:
a1
a2
a3
b1
b2
b3
c1
c2
c3

