使用 ksh 的"查找"命令循环的异常行为



我在KSH脚本中观察到一种非常奇怪的行为,但我无法找出背后的原因。我希望有人可以对此做出解释!

脚本流程:

  1. 循环访问目录中的文件以创建批处理文件,以便批量处理输入文件。例如:输入文件

    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 循环。

    Process 检查两个文件中是否包含
  1. "abc",另外两个文件中是否包含"def"。

  2. Process 创建 project_1.batch,在两个单独的行中包含两个文件的名称。

    $cat project_1.batch
    $sample_abc_20180910.txt
    $sample_abc_20180911.txt
    

同样,进程会在两个单独的行中创建包含其他两个文件名称的 project_2.batch。

  1. 接下来,我遍历两个 .batch 文件,它按预期运行。 for 循环一次选取一个 .batch 文件并继续...

    for bf in `find $dataindir -maxdepth 1 -type f -name "*.batch" | sort -n`
    do
    echo $bf
    #intermediate process
    done
    
  2. 但是,我使用相同的命令(但使用不同的 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

^^^^ 请注意两个文件名之间包含的新行字符。

为什么带有 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 或换行分隔条目的几个原因之一。

最新更新