使用ksh的Find命令进行循环的异常行为

时间:2018-10-24 12:43:24

标签: linux shell for-loop find 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循环。

  1. 进程检查两个文件中是否包含“ abc”,其他两个文件中是否包含“ def”。

  2. 流程将创建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

^^^^请注意,两个文件名之间包含换行符。

为什么带查找命令的for循环一次起作用,而另一次却不起作用?我最终必须使用以下命令使脚本正常工作,但是为什么find命令不能像上一次一样工作?!

for file in $dataindir/project_*.batch

1 个答案:

答案 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或换行符分隔的条目的几个原因之一。

相关问题