以下是我需要将数据分离到数组中的代码,但是使用PIPE它正在生成子shell,因此无法访问数组normal,executable和directory.and它不能打印任何内容或者不会打印任何内容。知道#////////之后发生了什么。请帮我解决这个问题。
i=0
j=0
k=0
normal[0]=
executable[0]=
directory[0]=
ls | while read line
do
if [ -f $line ];then
#echo "this is normal file>> $line"
normal[i]=$line
i=$((i+1))
fi
if [ -x $line ];then
#echo "this is executable file>> $line"
executable[j]=$line
j=$((j+1))
fi
if [ -d $line ];then
#echo "this is directory>> $line"
directory[k]=$line
k=$((k+1))
fi
done
#//////////////////////////////////////
echo "normal files are"
for k in "${normal[@]}"
do
echo "$k"
done
echo "executable files are"
for k in "${executable[@]}"
do
echo "$k"
done
echo "directories are"
for k in "${directory[@]}"
do
echo "$k"
done
答案 0 :(得分:1)
您的脚本有几个缺陷:
您的if
测试应使用[[
而不是[
编写,这是用于二进制比较(更多信息:here)。如果您想保留[
或未使用bash
,则必须引用line
变量,即写下您所有的测试:if [ -f "$line" ];then
不要使用ls
列出当前目录,因为在某些情况下它会出错。在您的情况下,glob更适合(更多信息:here)
如果您想避免使用管道,请改用for
循环。将ls | while read line
替换为for line in $(ls)
或者,将我之前的积分改为for line in *
在这样做之后,我测试了你的脚本,它工作得非常好。您应该注意,某些文件夹将在“可执行文件”和“目录”下列出,因为它们具有+x
权限(我不知道这是否是您想要的行为)。
作为旁注,在使用它们之前,您不需要在bash中声明变量。因此,您的前6行不是必需的。变量i,j,k不是必需的,您可以使用以下语法动态递增数组:normal+=("$line")
。
答案 1 :(得分:0)
最简单的方法是在不再需要数组之前保持子shell打开。换句话说:
ls | { while read line; do
...
echo "directories: ${directory[@]}" | tr ' ' \\n
}
换句话说,在while
之前添加一个左大括号,在脚本末尾添加一个右大括号。