4

我不确定我完全理解为什么:

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格式不同,但我不确定。我什至试图放在evalls 前面...

4

3 回答 3

11

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

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

使用forglob 模式,然后引用文件名的所有引用是使用可能包含空格的文件名的最安全方法。

于 2012-12-12T01:26:35.400 回答
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”了。

于 2012-12-12T01:14:38.230 回答
2

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

而且,正如其他人所提到的,如果可以通过globbing来实现,则应避免使用其中任何一个。

于 2012-12-12T01:18:05.397 回答