ksh:shell脚本,以定期间隔搜索目录中存在的所有文件中的字符串

时间:2014-01-30 06:51:45

标签: shell unix ksh

我在unix(SUN)中有一个目录(输出)。使用文件名的时间戳前缀创建了两种类型的文件。这些文件定期创建10分钟。 即g:

1.  20140129_170343_fail.csv (some lines are there)
2.  20140129_170343_success.csv (some lines are there)

现在我必须在输出目录中的所有文件中搜索特定字符串,如果在失败和成功文件中找到该字符串,我必须计算这些文件中存在的行数并将输出保存到cnt_succcnt_fail个变量。如果找不到该字符串,我将在20秒的睡眠定时器后再次在同一目录中搜索。

这是我的代码

#!/usr/bin/ksh

for i in 1 2
do
  grep -l 0140127_123933_part_hg_log_status.csv /osp/local/var/log/tool2/final_logs/* >log_t.txt;  ###  log_t.txt will contain all the matching file list
  while read line   ### reading the log_t.txt
  do
    echo "$line has following count"
    CNT=`wc -l $line|tr -s " "|cut -d" " -f2`
    CNT=`expr $CNT - 1`
    echo $CNT
  done <log_t.txt
  if [ $CNT > 0 ]
  then
    exit
  fi

  echo "waiitng"
  sleep 20
done

我遇到的问题是,我无法在文件中获取_success和_fail并查看其计数

4 个答案:

答案 0 :(得分:1)

我不确定ksh,但while ... do; ... done因使用bash中使用的任何变量而失败而臭名昭着。 ksh可能类似。

如果我理解你的问题,SunOS有grepuniqsort AFAIK,那么可能的选择可能是......

首先:

$ cat fail.txt
W34523TERG
ADFLKJ
W34523TERG
WER
ASDTQ34T
DBVSER6
W34523TERG
ASDTQ34T
DBVSER6

$ cat success.txt
abcde
defgh
234523452
vxczvzxc
jkl
vxczvzxc
asdf
234523452
vxczvzxc
dlkjhgl
jkl
wer
234523452
vxczvzxc

现在:

egrep "W34523TERG|ASDTQ34T" fail.txt | sort | uniq -c
    2 ASDTQ34T
    3 W34523TERG

egrep "234523452|vxczvzxc|jkl" success.txt | sort | uniq -c
    3 234523452
    2 jkl
    4 vxczvzxc

根据输入数据,您可能希望查看sort在您的系统上有哪些选项。检查uniq的选项可能也很有用(它可以做的不仅仅是重复计算)。

答案 1 :(得分:1)

认为你想要这样的东西(将同时适用于

#!/bin/ksh

while read -r file; do
  lines=$(wc -l < "$file")
  ((sum+=$lines))
done < <(grep -Rl --include="[1|2]*_fail.csv" "somestring")
echo "$sum"

请注意,这将匹配以12开头并以_fail.csv结尾的文件,并不完全清楚这是否是您想要的。

e.g。假设我有两个文件,一个以1开头(包含4行),另一个以2开头(包含3行),两个文件都以_ _fail.csv结尾,位于我当前工作目录下的某个位置

> abovescript
7

了解grep选项很重要

   -R, --dereference-recursive
          Read all files under each directory,  recursively.   Follow  all
          symbolic links, unlike -r.

   -l, --files-with-matches
          Suppress  normal  output;  instead  print the name of each input
          file from which output would normally have  been  printed.   The
          scanning  will  stop  on  the  first match.  (-l is specified by
          POSIX.)

答案 2 :(得分:1)

最后我能找到解决方案。这是完整的代码:

#!/usr/bin/ksh


file_name="0140127_123933.csv"

for i in 1 2
do

grep -l $file_name /osp/local/var/log/tool2/final_logs/* >log_t.txt;

    while read line
    do
    if [ $(echo "$line" |awk '/success/') ]           ## will check the success file
    then
    CNT_SUCC=`wc -l $line|tr -s " "|cut -d" " -f2`
    CNT_SUCC=`expr $CNT_SUCC - 1`

    fi

    if [ $(echo "$line" |awk '/fail/') ]             ## will check the fail file
    then
    CNT_FAIL=`wc -l $line|tr -s " "|cut -d" " -f2`
    CNT_FAIL=`expr $CNT_FAIL - 1`

    fi
    done <log_t.txt
    if [ $CNT_SUCC > 0 ] && [ $CNT_FAIL > 0 ]
    then
            echo " Fail count = $CNT_FAIL"
            echo " Success count =  $CNT_SUCC"
            exit
    fi

   echo "waitng for next search..."
   sleep 10
   done

感谢大家的帮助。

答案 3 :(得分:0)

我不认为我做对了,但是你不能对这些文件进行扩散吗?

也许试试:

#...
CNT=`expr $CNT - 1`
if [ $(echo $line | grep -o "fail") ]
then
    #do something with fail count
else
    #do something with success count
fi