0

enter image description here---- my text file from which i have to search for the keywords [name of the file --- test] <cat -Evt file>

    centos is my bro$
    red hat is my course$
    ubuntu is my OS$
    fqdn is stupid $
    $
    $
    $
    tom outsmart jerry$
    red hat is my boy$
    jerry is samall 

------ keyword file is [word.txt] <cat -Evt file >

  red hat$
  we$
  hello$
  bye$
  Compensation

----- my code

  while read "p"; do
  paste  -d',' <(echo -n  "$p" ) <(echo "searchall") <(  grep -i "$p" test | wc -l) <(grep  -i -A 1  -B 1   "$p" test )
  done <word.txt
   

---- my expectation ,output should be

 keyword,serchall,frequency,line above it
                            line it find keyword in
                            line below  it
              
 red hat,searchall,2,centos is my bro
                     red hat is my course
                     ubuntu is my OS                                
            
 red hat,searchall,2,tom outsmart jerry
                     red hat is my boy
                     jerry is samall

---- but coming OUTPUT from my code

  red hat,searchall,2,centos is my bro
  ,,,red hat is my course
  ,,,ubuntu is my OS
  ,,,--
  ,,,tom outsmart jerry
  ,,,red hat is my boy
  ,,,jerry is samall

---- please give me suggestion and point me in the right direction to get the desired output.

---- i am trying to grep the keyword from the file and printing them Here two records should create as keyword (red hat) is coming two time

----how can i loop through the coming frequency of the keyword.

  • What would the output be if `red hat` appeared on 2 lines of your input file? What if it never appeared at all? If `red hate` existed in your input file, should it be matched by `red hat` in your "keywords" file? In other words are you trying to do partial or full matches? Also, are you trying to to regexp or literal string matches? – Ed Morton Aug 15 '20 at 02:52
  • @EdMorton yes you are right sir, in my input file keywords are coming on 2 lines back to back that is one issue .2nd is i am new to coding and bash can you provide comments or reference in the give code so that i can understand how it is working sir – Aditya Singh Aug 19 '20 at 13:38
  • that doesn't answer my questions. Please try to figure out my code yourself as it's pretty simple (read the man page, add print statements to see which variables have which values, etc.) and if you have any specific questions then ask them under my answer. – Ed Morton Aug 19 '20 at 13:46

2 Answers2

1

This sounds very much like a homework assignment.
c.f. BashFAQ for better reads; keeping this simple to focus on what you asked for.

Rewritten for more precise formatting -

while read key                          # read each search key 
do cnt=$(grep "$key" test|wc -l)        # count the hits
   pad="$key,searchall,$cnt,"           # build the "header" fields
   while read line                      # read the input from grep
   do if [[ "$line" =~ ^-- ]]           # treat hits separately
      then pad="$key,searchall,$cnt,"   # reset the "header"
           echo                         # add the blank line
           continue                     # skip to next line of data
      fi
      echo "$pad$line"                  # echo "header" and data
      pad="${pad//?/ }"                 # convert header to spacving
   done < <( grep -B1 -A1 "$key" test ) # pull hits for this key
   echo                                 # add blank lines between
done < word.txt                         # set stdin for the outer read                       

$: cat word.txt
course
red hat

$: ./tst
course,searchall,1,centos is my bro
                   red hat is my course
                   ubuntu is my OS

red hat,searchall,2,centos is my bro
                    red hat is my course
                    ubuntu is my OS

red hat,searchall,2,tom outsmart jerry
                    red hat is my boy
                    jerry is samall
Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
0

This will produce the expected output based on one interpretation of your requirements and should be easy to modify if I've made any wrong guesses about what you want to do:

$ cat tst.awk
BEGIN {
    RS = ""
    FS = "\n"
}
{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") }
NR == FNR {
    words[$0]
    next
}
{
    for (word in words) {
        for (i=1; i<=NF; i++) {
            if ($i ~ word) {
                map[word,++cnt[word]] = (i>1 ? $(i-1) : "") FS $i FS $(i+1)
            }
        }
    }
}
END {
    for (word in words) {
        for (i=1; i<=cnt[word]; i++) {
            beg = sprintf("%s,searchall,%d,", word, cnt[word])
            split(map[word,i],lines)
            for (j=1; j in lines; j++) {
                print beg lines[j]
                beg = sprintf("%*s",length(beg),"")
            }
            print ""
        }
    }
}

.

$ awk -f tst.awk words file
red hat,searchall,2,centos is my bro
                    red hat is my course
                    ubuntu is my OS

red hat,searchall,2,tom outsmart jerry
                    red hat is my boy
                    jerry is samall

I assumed your real input doesn't start with a bunch of blanks as in your posted example - if it does that's easy to accommodate.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • sir this code doesn't run , i am running the same command awk -f words file ,< words > contain keywords and contain text – Aditya Singh Aug 22 '20 at 08:16
  • The script I posted when run the way I show can't do that so you're doing something wrong but idk what it is as I can't see your desktop. Are you running it using exactly the sample input you provided in your question or against some different set of input? What do you mean by `doesn't run`? Does it execute but produce no output or does the process hang like it's waiting for input? What happens if you add `print` statements on the line after every `{`? – Ed Morton Aug 22 '20 at 12:16
  • sir it executes ( awk -f tst.awk words file) but doesn't print anything and my two files are the same test--where the content is and words ---where keywords are – Aditya Singh Aug 22 '20 at 13:21
  • sir i have add the pic – Aditya Singh Aug 22 '20 at 13:35
  • I fixed one bug that'd cause the output to appear all on 1 line instead of on 3 lines at a time but that wouldn't cause your problem. From the image you posted (and please don't post images - post text) it **looks like** the script in the background is the same as mine so then the only way you wouldn't be getting any output would be if none of the "words" in your words file match any of the lines in your other file. – Ed Morton Aug 22 '20 at 14:14
  • Is it possible that your input files have DOS line endings (see https://stackoverflow.com/questions/45772525/why-does-my-tool-output-overwrite-itself-and-how-do-i-fix-it?noredirect=1#comment97778025_45772525)? Run `cat -Evt words` and `cat -Evt file` and post the output **as copy/pasted text** in your question. – Ed Morton Aug 22 '20 at 14:15
  • Also, unrelated to your problem but I see you named the file that contains your awk script as `4.sh`, don't do that as it's misleading since it contains an awk script, not a shell script. – Ed Morton Aug 22 '20 at 14:18
  • sir only $ symbol is coming at the end of the line , i have edit in my que above – Aditya Singh Aug 22 '20 at 19:33
  • Does every line of your words file **really** start with spaces? I assumed that was just a formatting problem in your question but if that's real then that'd certainly cause a problem. I've updated my script now to handle that or trailing spaces. If that's not it, then idk - just add some `print` statements to debug as I suggested earlier. – Ed Morton Aug 22 '20 at 20:41