使用 ksh 使用 Find 命令进行循环的异常行为
Unusual behavior for loop with Find command using ksh
我在我的 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 文件并按预期 运行s。
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 循环中 运行 a cat on $ef 时,出现错误
cat: /home/userdir/project/project_2.batch
/home/userdir/project/project_1.batch: No such file or directory
^^^^ 注意两个文件名之间包含换行符。
为什么带 find 命令的 for 循环一次有效,而另一次无效?我最终不得不使用以下命令使脚本工作,但为什么 find 命令不能像上次那样工作?!
for file in $dataindir/project_*.batch
当您修改 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 或换行符分隔的条目的几个原因之一。
我在我的 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 文件并按预期 运行s。 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 循环中 运行 a cat on $ef 时,出现错误
cat: /home/userdir/project/project_2.batch
/home/userdir/project/project_1.batch: No such file or directory
^^^^ 注意两个文件名之间包含换行符。
为什么带 find 命令的 for 循环一次有效,而另一次无效?我最终不得不使用以下命令使脚本工作,但为什么 find 命令不能像上次那样工作?!
for file in $dataindir/project_*.batch
当您修改 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 或换行符分隔的条目的几个原因之一。