使用ls和find在bash脚本中循环遍历文件之间的区别

时间:2012-12-11 23:07:13

标签: bash unix find ls

我不确定我理解为什么:

for f in `find . -name "strain_flame_00*.dat"`; do
   echo $f
   mybase=`basename $f .dat`
   echo $mybase
done

工作并且:

for f in `ls strain_flame_00*.dat`; do
   echo $f
   mybase=`basename $f .dat`
   echo $mybase
done

没有,即文件名不会被删除后缀。我认为这是因为ls的结果格式不同,但我不确定。我甚至试图将eval放在ls ...

前面

3 个答案:

答案 0 :(得分:9)

在这里迭代文件名的正确方法是

for f in strain_flame_00*.dat; do
   echo "$f"
   mybase=$(basename "$f" .dat)
   echo "$mybase"
done

使用带有glob模式的for,然后引用对文件名的所有引用是使用可能有空格的文件名的最安全的方法。

答案 1 :(得分:4)

首先,永远不要解析ls命令的输出。

如果你必须使用ls并且你不知道那里有ls别名,那么这样做:

(
COLUMNS=
LANG=
NLSPATH=
GLOBIGNORE=
LS_COLORS=
TZ=
unset ls
for f in `ls -1 strain_flame_00*.dat`; do
  echo $f
  mybase=`basename $f .dat`
  echo $mybase
done
)

它用括号括起来保护现有的环境,别名和shell变量。

各种环境名称都是NUKED(因为ls看起来确实如此)。

一个unalias命令(不言自明)。

一个未设置的命令(再一次,保护免受一丝不苟的'ls'功能)。

现在,你可以看到为什么不使用'ls'。

答案 2 :(得分:1)

尚未提及的另一个区别是默认情况下find是递归搜索,而ls则不是。{1}}。 (尽管两者都可以被告知通过选项进行递归/非递归;并且可以告诉find递归到指定的深度)

并且,正如其他人所提到的,如果可以通过globbing来实现,那么你应该避免使用它们。