使用ls进行迭代并使用-f进行检查并不起作用

时间:2017-04-06 10:43:39

标签: 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

2 个答案:

答案 0 :(得分:1)

您的方法可能会出错。这样做。

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输出不是一个好主意(参见http://mywiki.wooledge.org/ParsingLs

  • 测试中的双引号变量扩展,再次允许包含空格,换行符的文件。

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

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

for i in "$@" ; do
    for j in "$i"/* ; do
       ! [ -f "$j" ] || echo "$j is a regular file!"
    done
done

如果您想使用find,则需要确保只列出深度为一级的文件(否则结果可能与您的代码不同)。你可以这样做:

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

请注意,这仍然会有所不同,因为通配(默认情况下)会排除以句点开头的文件。将shopt -s dotglob添加到基于循环的解决方案将允许globbing考虑所有文件,这应该使两个解决方案对相同的文件进行操作。

答案 1 :(得分:-1)

我认为您最好使用find

find $@ -type f