这是我的bash脚本的一个小但[完整]部分,如果从存储的数组中获取前缀,它将查找并输出mydir中的所有文件。我注意到的奇怪的是,如果我从脚本中取出“-maxdepth 1 -name”,这个脚本就可以正常运行,否则它只会给我带有数组中第一个元素前缀的文件。
如果有人向我解释这一点会很有帮助。提前抱歉,如果有一些事我看起来很傻。我对脚本编程比较陌生。
#!/bin/sh
DIS_ARRAY=(A B C D)
echo "Array is : "
echo ${DIS_ARRAY[*]}
for dis in $DIS_ARRAY
do
IN_FILES=`find /mydir -maxdepth 1 -name "$dis*.xml"`
for file in $IN_FILES
do
echo $file
done
done
输出:
/mydir/Abc.xml
/mydir/Ab.xml
/mydir/Ac.xml
预期产出:
/mydir/Abc.xml
/mydir/Ab.xml
/mydir/Ac.xml
/mydir/Bc.xml
/mydir/Cb.xml
/mydir/Dc.xml
答案 0 :(得分:2)
循环被打破了。
之所以如此IN_FILES=`find mydir -maxdepth 1 -name "$dis*.xml"`
有效,而
IN_FILES=`find mydir "$dis*.xml"`
不是因为在第一个中,您指定了-name
。在第二个中,find
列出了mydir
中的所有文件。如果您将第二个更改为
IN_FILES=`find mydir -name "$dis*.xml"`
你会看到循环不起作用。
正如评论中所提到的,您当前使用的语法$DIS_ARRAY
只会为您提供数组的第一个元素。
尝试将循环更改为:
for dis in "${DIS_ARRAY[@]}"
在这种情况下,周围的双引号不是必需的,所以你可以这样做:
for dis in ${DIS_ARRAY[@]}
如果数组包含空格,则需要引号,例如,如果要循环遍历数组arr=( "a a" "b b" )
。
这是一个测试,显示正在发生的事情:
#!/bin/sh
arr=("a a" "b b")
echo using '$arr'
for i in $arr; do echo $i; done
echo using '${arr[@]}'
for i in ${arr[@]}; do echo $i; done
echo using '"${arr[@]}"'
for i in "${arr[@]}"; do echo $i; done
输出:
using $arr
a
a
using ${arr[@]}
a
a
b
b
using "${arr[@]}"
a a
b b
有关详细信息,请参阅此related question。
答案 1 :(得分:2)
@ TomFenech的回答解决了您的问题,但让我建议其他改进:
#!/usr/bin/env bash
DIS_ARRAY=(A B C D)
echo "Array is : "
echo ${DIS_ARRAY[*]}
for dis in "${DIS_ARRAY[@]}"
do
for file in "/mydir/$dis"*.xml
do
if [ -f "$file" ]; then
echo "$file"
fi
done
done
sh
,但您的问题已标记为bash
- 除非您需要POSIX合规性,否则请使用bash
shebang行来充分利用所有bash
必须提供find
和命令替换。*
以确保路径名扩展。nullglob
shell选项为OFF,默认情况下为OFF),因此循环输入一次,文件名无效(未扩展的glob) - 因此[ -f "$file" ]
有条件确保找到实际的匹配(作为旁白:使用bashisms,你可以使用[[ -f $file ]]
代替。)