【问题标题】:Unusual behavior for loop with Find command using ksh使用 ksh 查找命令的循环异常行为
【发布时间】:2019-03-28 21:19:46
【问题描述】:

我在我的 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. 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 时,出现错误

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

【问题讨论】:

    标签: linux shell for-loop find ksh


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

    【讨论】:

    • 你先生,真是个天才!!我正在设置 IFS='|'在我点击第二个 for 循环之前,因为我没有重置 IFS,所以它导致了问题。
    • 顺便说一句...我喜欢您建议使用 while 读取循环而不是命令扩展的 for 循环。谢谢!
    猜你喜欢
    • 2023-03-15
    • 2014-04-17
    • 1970-01-01
    • 2018-03-26
    • 2017-07-08
    • 1970-01-01
    • 2018-06-18
    • 1970-01-01
    • 2014-07-01
    相关资源
    最近更新 更多