0

Using the awk command, I am to display lines 3-5 backwards of a file i have created and before the outputted line, the line number is to be displayed (i.e. line 3:). I am also to display the total wordcount of all three lines. My code is provided below. I keep obtaining an error message for the '%s' and not sure where to go from here, any help?

BEGIN { print("<< Start of file >>"); }

NR>=3 && NR<=5 { for (i = NF; i >= 1; i--)

                printf "%d: %s ", $i;
                print ""
                wordCount += NF;


}



END { printf "<< End of file: wordCount = %d >>\n", wordCount }

Here's the input file:

Gimme presents I want more!
Gimme presents, I did my chores!
A bicycle, a tricycle, a motor vehicle!
I deserve it, you reverse it!
Gimme presents; more, more, more
Gimme presents I need more!

And the out put i obtain is:

(FILENAME=presents FNR=3) fatal: not enough arguments to satisfy format string
        `%d: %s '
             ^ ran out for this one
4
  • 3
    Can you post example of your input and desired output ? Feb 9, 2018 at 0:11
  • Also, you mentioned error for %s. Please post the exact text of error that you're getting. Feb 9, 2018 at 0:13
  • it has been updated, sorry for the confusion!
    – Herman
    Feb 9, 2018 at 0:16
  • 1
    Aha, I see the issue. printf "%d: %s ", $i; The %d matches for $i but there's nothing you provide to match for %s. I'll put it in an answer shortly Feb 9, 2018 at 0:17

1 Answer 1

1

Code bug portion

Key issue is that you have %d: %s format, but there's only one argument $i to match the format speficiers, i.e. $i matches with %d but not with %s.

Once you change the script as so:

#!/usr/bin/awk -f

BEGIN { print("<< Start of file >>"); }

NR>=3 && NR<=5 { 
    for (i = NF; i >= 1; i--)
        printf "%d: %s ", i,$i;
    print ""
    wordCount += NF;


}

END { printf "<< End of file: wordCount = %d >>\n", wordCount }

Then there's no error, and produces output as so:

$ ./awk_script.awk input.txt
<< Start of file >>
7: vehicle! 6: motor 5: a 4: tricycle, 3: a 2: bicycle, 1: A 
6: it! 5: reverse 4: you 3: it, 2: deserve 1: I 
5: more 4: more, 3: more, 2: presents; 1: Gimme 
<< End of file: wordCount = 18 >>

Fixing code to match desired behavior

However, your description was:

I am to display lines 3-5 backwards of a file i have created and before the outputted line, the line number is to be displayed (i.e. line 3:)

That means before processing each field using for-loop, you need to output line number first:

#!/usr/bin/awk -f

BEGIN { print("<< Start of file >>"); }

NR>=3 && NR<=5 {
    printf "line %d:",NR; # display line number first
    for (i = NF; i >= 1; i--)
        printf " %s ", $i;
    print ""; 
    wordCount += NF;

}

END { printf "<< End of file: wordCount = %d >>\n", wordCount }

Which works as so:

$ ./awk_script.awk input.txt
<< Start of file >>
line 3: vehicle!  motor  a  tricycle,  a  bicycle,  A 
line 4: it!  reverse  you  it,  deserve  I 
line 5: more  more,  more,  presents;  Gimme 
<< End of file: wordCount = 18 >>
8
  • Wow! such a simple fix, upvote! One more thing, how would we rid the text from repeating itself with the original pattern, as it is appended to the reversed line in the output?
    – Herman
    Feb 9, 2018 at 0:36
  • I figured it out, had to remove the 'print;' line!
    – Herman
    Feb 9, 2018 at 0:46
  • Oops, sorry, the print "" was necessary. Occasionally small details like that escape my attention :) Feb 9, 2018 at 0:49
  • It looks like you're just using print "" in order to tack on a newline. How about just adding \n to the end of the printf format argument instead? @HermanTravis
    – Wildcard
    Feb 9, 2018 at 1:01
  • 1
    @Wildcard That's of course if you're talking about changing printf " %s ", $i; into printf " %s \n", $i;. Remember that the printf part is inside for loop. If you mean printf "\n" after (!) the for loop, then it's OK Feb 9, 2018 at 1:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.