在ksh中逐行读取文件

时间:2012-12-26 12:57:45

标签: ksh

我们使用一些名为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

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

1 个答案:

答案 0 :(得分:4)

写下以下所有内容,然后注意到你的grep声明。 回想一下,ksh不支持..作为'扩展此值范围'的指标。 (我认为这是你的意图)。由于缺乏grep的引用参数,它也变得模棱两可。如果你使用shell将转换的语法,那么你真的不知道什么reg-exp被发送到grep。总是更好地引用争论,除非你确定你需要不带引号的值。尝试重写为

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

另外,你是故意使用'match any char'操作符'。'或者你想只匹配一个句号char?如果您只想匹配一个句点,那么您需要像\.一样转义它。

最后,如果您正在处理的任何文件是在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 greps,+ tail?你应该能够轻松地看到你失去输出的地方。

IHTH