在bash脚本中使用ls和find对文件进行循环的区别
我不确定我是否完全理解原因:在bash脚本中使用ls和find对文件进行循环的区别,bash,unix,find,ls,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 不,即文件名没有去掉后缀。我想这
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前面 首先,不要解析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变量
各种环境名称都被核化(正如ls
查找这些名称一样)
一个unalias命令(不言自明)
一个未设置的命令(同样,防止“ls”功能过度使用)
现在,您可以看到为什么不使用“ls”。另一个尚未提及的区别是,
find
默认为递归搜索,而ls
则不是。(即使可以通过选项告知两者执行递归/非递归;并且可以告知find
递归到指定深度)
而且,正如其他人所提到的,如果可以通过实现,您应该避免使用任何一种方法。在这里迭代文件名的正确方法是
for f in strain_flame_00*.dat; do
echo "$f"
mybase=$(basename "$f" .dat)
echo "$mybase"
done
使用带有glob模式的
for
,然后引用对文件名的所有引用,是使用可能有空格的文件名的最安全的方法。如果您只有一个简单的glob,那么为什么您会使用其中任何一个呢?当然,但我想理解为什么不同的行为……永远不会解析ls
的输出!您还可以使用find-名称“应变火焰00*.dat”-执行基名称“{}”.dat\
要在每个匹配的文件上执行命令而不是取消关联(可能有ls
函数),请使用command ls
注意,当目录中有太多文件时,这是不安全的-您可能会达到bash的限制。