-3

I am having text file of the following type,

a b c d -- -- -- -- 1 ok device issue Some Action which has to be taken which is split into many lines under d. 

I have tried using grep for "issue" however only the first line of 'd' gets printed. The output I got is:

1 ok device issue Some Action which 

However I want the complete output in d. When I tried saving the file in csv it showed the second line of column d as a new line.

Edit:

The output is obtained from multiple device which stored in a variable from which I am grepping for the one's which are having issues.

9
  • That's happening because what's under d is multiple lines. grep is working in the way that it's designed. awk will do the same thing if you use it to search for issue and then print. Your only option is to make d one line.CommentedAug 13, 2020 at 0:33
  • what Nasir Riley said, except that you can use awk in a way to match the whole column if you reassign Record Separator and Field Separator.CommentedAug 13, 2020 at 1:25
  • @Ramana can you attach the actual text file?CommentedAug 13, 2020 at 1:59
  • grep -E 'issue|^ , or use perl.CommentedAug 13, 2020 at 2:06
  • GNU awk can do fixed-width processing with the FIELDWIDTHS variable. Check the manualCommentedAug 13, 2020 at 3:36

4 Answers 4

1

You need multi line grepping here. For which we will need the PCRE enabled -P option. Since grep will output Null delimited records in the slurp -z mode we remove those via tr command.

$ < file grep -Pzo '.*\S.*issue.*\n(?:\h+.*\n)+' | tr -d '\0' 
    0

    grep is acting like it should in default mode. From its man page:

    ...grep searches for PATTERNS in each FILE. PATTERNS is one or more patterns separated by newline characters, and grep prints each line that matches a pattern...

    So, it's supposed to turn up lines in the text matching a regex. Lines are demarcated by the newline control code, which explains the behavior you are seeing. Other than using the -z option mentioned in the responses. Assuming "issue" is the regex you want to match (replace with 'Device Degraded' or '\sDegraded' or '\sError' if that's what you are actually looking to match); and that the "Corrective Action" column is machine generated and consistent, i.e., always spanning 4 lines you could also simply just run grep -A 3 '\sissue' > issues to save only the lines you are interested in into a file. You must be able to generate output which looks like:

    1 ok device issue Some Action which has to be taken which is split into many lines under d. -- 10 ok device issue Some Action which has to be taken which is split into may lines under d. -- 211 ok device issue Some Action which has to be taken which is split into many lines under d. 

    check grep's man page to find out more about what these options do.

      0

      Assuming a "record" in the input file is exactly as provided by the OP:

      $ sed '/issue/!d; :a; n; /^[0-9]\{1,\} /d; $!ba' file 1 ok device issue Some Action which has to be taken which is split into many lines under d. $ 
        0

        This might be what you want, using any awk in any shell on every UNIX box:

        $ cat tst.awk /^[0-9]/ { prt() } { rec = rec $0 ORS } END { prt() } function prt() { if ( rec ~ regexp ) { printf "%s", rec } rec = "" } 

        .

        $ awk -v regexp='issue' -f tst.awk file 1 ok device issue Some Action which has to be taken which is split into many lines under d. 

          You must log in to answer this question.

          Start asking to get answers

          Find the answer to your question by asking.

          Ask question

          Explore related questions

          See similar questions with these tags.