我在KSH脚本中观察到一个非常奇怪的行为,并且我无法弄清其背后的原因。我希望有人对此有所解释!
脚本流:
遍历目录中的文件以创建用于批量处理输入文件的批处理文件。例如:输入文件
sample_abc_20180910.txt
sample_abc_20180911.txt
sample_def_20180910.txt
sample_def_20180911.txt;
脚本使用以下命令循环遍历文件:
for f in `find $dataindir -maxdepth 1 -type f -name "sample_*.txt" | sort -n`
此for循环按预期工作-一次拾取一个文件,然后继续for循环。
进程检查两个文件中是否包含“ abc”,其他两个文件中是否包含“ def”。
流程将创建project_1.batch,其中在两个单独的行中包含两个文件的名称。
$cat project_1.batch
$sample_abc_20180910.txt
$sample_abc_20180911.txt
类似地,进程创建project_2.batch,其中在单独的两行中包含其他两个文件的名称。
接下来,我遍历两个.batch文件,该文件将按预期运行。 for循环一次拾取一个.batch文件并继续...
for bf in `find $dataindir -maxdepth 1 -type f -name "*.batch" | sort -n`
do
echo $bf
#intermediate process
done
但是,我使用相同的命令(但使用不同的for循环变量)在单独的for循环中第二次遍历.batch文件,这一次的结果很奇怪! for循环可一次性拾取两个.batch文件!
for ef in `find $dataindir -maxdepth 1 -type f -name "*.batch" | sort -n`
do
echo $ef
#intermediate process
done
$/home/userdir/project/project_2.batch
$/home/userdir/project/project_1.batch
随后,当我尝试在for循环中的$ ef上运行一只猫时,出现错误
cat: /home/userdir/project/project_2.batch
/home/userdir/project/project_1.batch: No such file or directory
^^^^请注意,两个文件名之间包含换行符。
为什么带查找命令的for循环一次起作用,而另一次却不起作用?我最终必须使用以下命令使脚本正常工作,但是为什么find命令不能像上一次一样工作?!
for file in $dataindir/project_*.batch
答案 0 :(得分:1)
当您修改IFS
(内部字段分隔符,它决定将哪些字符分隔未引号的命令扩展)时,会发生这种情况:
$ grep '' *
hello.txt:hello
world.txt:world
$ for f in `find . -name '*.txt'`; do cat "$f"; done
hello
world
$ IFS=':'
(no output)
$ for f in `find . -name '*.txt'`; do cat "$f"; done
cat: ./hello.txt
./world.txt: No such file or directory
这是为什么应避免在命令扩展上进行for
循环,而改为使用while read
循环读取NUL或换行符分隔的条目的几个原因之一。