【问题标题】:Reading a file line by line in ksh在 ksh 中逐行读取文件
【发布时间】:2012-12-26 12:57:45
【问题描述】:

我们使用了一些叫做 Autosys 的包,这个包有一些特定的命令。我有一个变量列表,我喜欢将其中一个 Autosys 命令作为变量一一传递。

例如一个这样的变量是 var1,使用这个 var1 我想启动一个类似这样的命令

autosys_showJobHistory.sh var1

现在,当我启动下面的书面命令时,它会给我所需的输出。

echo "var1" | while read line; do autosys_showJobHistory.sh $line | grep 1[1..6]:[0..9][0..9] | grep 24.12.2012 | tail -1 ; done

但是,如果我将 var1 放在一个文件中,比如 Test.txt 并使用 cat 启动相同的命令,它什么也没给我。我的印象是命令 autosys_showJobHistory.sh 在这种情况下不起作用。

cat Test.txt | while read line; do autosys_showJobHistory.sh $line | grep 1[1..6]:[0..9][0..9] | grep 24.12.2012 | tail -1 ; done

我在第二个命令中做错了什么?

【问题讨论】:

    标签: ksh


    【解决方案1】:

    写了以下所有内容,然后注意到您的 grep 语句。 回想一下,ksh 不支持将.. 作为“扩展此值范围”的指标。 (我认为这是你的意图)。由于您没有引用 grep 的参数,这也变得模棱两可。如果您使用的是 shell 将转换的语法,那么您将不会真正知道将什么 reg-exp 发送到 grep。总是最好引用参数,除非您确定需要未引用的值。尝试重写为

    grep '1[1-6]:[0-9][0-9]' | grep '24.12.2012' 
    

    另外,您是否故意使用“匹配任何字符”运算符“。”还是您只想匹配句点字符?如果您只想匹配一个句点,那么您需要像\. 一样对其进行转义。

    最后,如果您正在处理的任何文件是在 Windows 机器上创建的,然后传输到 Unix/Linux,则很可能是行尾 (Ctrl-MCtrl-J) (\r\n) 导致你的问题。使用dos2unix file [file2 ...] 清理基于 PC 的文件(或任何通过 ftp 发送的文件)。


    如果上述方法没有帮助,您将不得不“分而治之”来调试您的问题。

    当我进行以下测试时,我得到了预期的输出

    $ echo "var1" | while read line ; do print "line=${line}" ; done
    line=var1
    $ vi Test.txt
    $ cat Test.txt
    var1
    $ cat Test.txt | while read line ; do print "line=${line}" ; done
    line=var1
    

    与您的问题无关,但肯定会引起评论的是您在这种情况下使用cat commnad,这将为您带来 UUOC 奖。可以改写为

    while read line ; do print "line=${line}" ; done < Test.txt
    

    但是要解决您的问题,现在打开 shell 调试/跟踪选项,或者通过更改脚本的顶行(shebang 行),例如

     #!/bin/ksh -vx
    

    或者通过使用匹配的对来跟踪这些行的状态,即

     set -vx
     while read line; do 
         print -u2 -- "#dbg: Line=${line}XX"
         autosys_showJobHistory.sh $line \
         | grep 1[1..6]:[0..9][0..9] \
         | grep 24.12.2012 \
         | tail -1 
     done  < Test.txt
     set +vx
    

    我添加了一个额外的调试步骤,print -u2 -- ....(u2=stderror,--关闭打印选项处理) 现在,您可以通过查看该输出来确保没有多余的空格或制表符出现。

    它们应该无关紧要,因为您没有引用您的 $line。作为测试的一部分,我建议像 "${line}" 一样引用它。

    然后我会注释掉尾部和 grep 行。你想看看是什么步骤导致这个中断,对吧?那么 autosys_script 本身是否仍会产生您期望的中间输出?那么 autosys + 1 grep 是否按预期产生,+2 grep,+ tail?您应该能够轻松查看丢失输出的位置。

    IHTH

    【讨论】:

      猜你喜欢
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 2011-06-15
      • 2010-12-24
      • 2016-02-04
      • 2019-04-16
      • 2012-02-04
      • 2010-11-19
      相关资源
      最近更新 更多