Linux 使用ls进行迭代并使用-f进行检查';行不通

Linux 使用ls进行迭代并使用-f进行检查';行不通,linux,bash,shell,Linux,Bash,Shell,我有一段代码应该可以工作,但它不能。 我想遍历命令行中给出的文件和目录的子目录,看看哪一个是文件。程序从不在if语句中输入任何条目 for i in $@;do for j in `ls $i`;do if [ -f $j ];then echo $j is a file! fi done done 你的方法可能会出问题。这样做 for i in "$@" ; do for j in "$i"/* ; do

我有一段代码应该可以工作,但它不能。 我想遍历命令行中给出的文件和目录的子目录,看看哪一个是文件。程序从不在if语句中输入任何条目

for i in $@;do
    for j in `ls $i`;do
       if [ -f $j ];then
          echo $j is a file!
       fi
    done
done

你的方法可能会出问题。这样做

for i in "$@" ; do
    for j in "$i"/* ; do
       if [ -f "$j" ]; then
          echo "$j is a regular file!"
       fi
    done
done
变化:

  • 引用
    “$@”
    ,以避免包含空格、换行符的文件路径出现问题

  • 在内部循环中使用shell globbing,因为解析
    ls
    输出不是一个好主意(请参阅)

  • 在测试内部进行双引号变量扩展,再次允许使用带有空格、换行符的文件

  • 在输出中添加“常规”,因为这是特定测试操作员测试的内容(例如,将排除与设备、FIFO相对应的文件,而不仅仅是目录)

如果您愿意,您可以简化一点:

for i in "$@" ; do
    for j in "$i"/* ; do
       ! [ -f "$j" ] || echo "$j is a regular file!"
    done
done
如果要使用
查找
,则需要确保只列出一个深度的文件(否则结果可能与代码不同)。您可以这样做:

find "$@" -mindepth 1 -maxdepth 1 -type f -exec echo "{} is a file" \;

请注意,这仍然会有点不同,因为globbing(默认情况下)排除以句点开头的文件。将<代码> Subto-dotLogb < /代码>添加到基于循环的解决方案中将允许Guffin考虑所有文件,这应该使两个解决方案都在相同的文件上运行。

< P>我认为您最好使用<代码>查找< /C> >:

find $@ -type f

问题太多,无法全部指出。。。请参阅,使用
查找“$@”-类型f
[与问题无关];一个好的做法是使变量名自解释,而不是
i
j
,您可以使用
myFolder
myFile
等来提高变量名的可读性code@WilliamPursell根据目的,您可能需要控制搜索的深度
find
执行,因为操作代码不会递归。