使用AWK查找第n行并将它们分配给变量

时间:2014-09-22 10:50:58

标签: bash unix awk hp-ux

好的,我有两个文件:一个是基线,另一个是生成的报告。我必须在两个文件匹配中验证特定字符串,它不仅仅是一个单词,请参见下面的示例:

.
.
name os ksd 
56633223223
some text..................
some text..................

我的搜索条件是找到唯一的号码,例如" 56633223223"并检索1行以上3行,我可以在基本文件和报告上执行此操作,然后比较它们是否匹配。总的来说,我需要shell脚本。

由于上面和下面的字符串是唯一的但行数不同,我把它放在一个名为" actlist":

的文件中
56633223223 1 5
56633223224 1 6
56633223225 1 3
.
.

现在从下面" Rcount"我得到了多少次迭代,并且在每次迭代中我必须得到第i行并查看单词count是否为3,如果是,那么将这些值变为变量形式并使用类似的东西

我被困在下面,要使用哪个命令。我正在考虑使用AWK,但如果有什么更好的请指教。这里有一些伪代码显示了我尝试做的事情:

xxxxx=/root/xxx/xxxxxxx
Rcount=`wc -l $xxxxx | awk -F " " '{print $1}'`

i=1
while ((i <= Rcount))
do
    record=_________________'(Awk command to retrieve ith(1st) record (of $xxxx),
    wcount=_________________'(Awk command to count the number of words in $record) 


    (( i=i+1 ))
done

注意:记录,wcount值稍后会打印到日志文件中。

4 个答案:

答案 0 :(得分:3)

听起来你正在寻找这样的东西:

#!/bin/bash

while read -r word1 word2 word3 junk; do
    if [[ -n "$word1" && -n "$word2" && -n "$word3" && -z "$junk" ]]; then
        echo "all good"
    else
        echo "error"
    fi
done < /root/shravan/actlist

这会遍历输入文件的每一行,将三列分配给word1word2word3-n测试read没有为每个变量分配空值。 -z检查只有三列,因此$junk为空。

答案 1 :(得分:1)

我承诺你这一切都错了。要在file1中查找单词并在file2和file3中搜索这些单词,只需:

awk '
NR==FNR{ for (i=1;i<=NF;i++) words[$i]; next }
{ for (word in words) if ($0 ~ word) print FILENAME, word }
' file1 file2 file3

或类似(假设一个简单的grep -f file1 file2 file3是不够的)。它不涉及shell循环来调用awk来提取字符串以保存在shell变量中以传递给其他shell命令等等。

到目前为止,您所做的只是要求我们帮助您实施您认为解决问题的部分内容,但我们正在努力做到这一点,因为您要求的内容没有意义对于你的问题听起来是什么样的合理解决方案的一部分,所以很难提出任何明智的建议。

如果你告诉我们你要做什么作为整个过程的样本输入和预期输出,那么我们可以帮助你。

我们似乎没有到达任何地方,所以让我们尝试一下我认为你可能想要的那种解决方案然后从那里拿走它。

并排查看这两个文件“旧”和“新”(由cat -n添加的行号):

$ paste old new | cat -n
     1  a               b
     2  b               56633223223
     3  56633223223     c
     4  c               d
     5  d               h
     6  e               56633223225
     7  f               i
     8  g               Z
     9  h               k
    10  56633223225     l
    11  i
    12  j
    13  k
    14  l

现在让我们来看看这个“actlist”:

$ cat actlist
56633223223 1 2
56633223225 1 3

并对上述所有3个文件运行此awk命令(是的,我知道它可以更简洁,更高效等等,但现在支持简单性和清晰度):

$ cat tst.awk                    
ARGIND==1 {
    numPre[$1] = $2
    numSuc[$1] = $3
}

ARGIND==2 {
    oldLine[FNR] = $0
    if ($0 in numPre) {
        oldHitFnr[$0] = FNR
    }
}

ARGIND==3 {
    newLine[FNR] = $0
    if ($0 in numPre) {
        newHitFnr[$0] = FNR
    }
}

END {
    for (str in numPre) {
        if ( str in oldHitFnr ) {
           if ( str in newHitFnr ) {
               for (i=-numPre[str]; i<=numSuc[str]; i++) {
                   oldFnr = oldHitFnr[str] + i
                   newFnr = newHitFnr[str] + i
                   if (oldLine[oldFnr] != newLine[newFnr]) {
                       print str, "mismatch at old line", oldFnr, "new line", newFnr
                       print "\t" oldLine[oldFnr], "vs", newLine[newFnr]
                   }
               }
           }
           else {
               print str, "is present in old file but not new file"
           }
        }
        else if (str in newHitFnr) {
           print str, "is present in new file but not old file"
        }
    }
}

$ awk -f tst.awk actlist old new
56633223225 mismatch at old line 12 new line 8
        j vs Z

它正在输出该结果,因为56633223225之后的第二行在文件“old”中是j但在文件“new”中是Z而文件“actlist”表示这两个文件必须是共同的之前的一行,直到该模式之后的3行。

这是你想要做的吗?以上使用GNU awk进行ARGIND,但其他方法的解决方法是微不足道的。

答案 2 :(得分:0)

使用以下代码:

awk '{if (NF == 3) { word1=$1; word2=$2; word3=$3; print "Words are:" word1, word2, word3} else {print "Line", NR, "is having", NF, "Words" }}' filename.txt

答案 3 :(得分:0)

我按照要求给出了解决方案。

awk '{                                          # awk starts from here and read a file line by line
if (NF == 3)                                    # It will check if current line is having 3 fields. NF represents number of fields in current line
{ word1=$1;                                     # If current line is having exact 3 fields then 1st field will be assigned to word1 variable
word2=$2;                                       # 2nd field will be assigned to word2 variable
word3=$3;                                   # 3rd field will be assigned to word3 variable
print word1, word2, word3}                      # It will print all 3 fields
}' filename.txt >> output.txt                   # THese 3 fields will be redirected to a file which can be used for further processing.

这是根据要求,但还有很多其他方法可以做到这一点但是它是用awk询问的。