Awk reverses both lines and words

I am new to programming and music, so I have to cancel awk all lines, as well as all words in these lines, from a file and print them.

"File1" to change:

aa bb cc

foo do how

And the output print "File1" should be as follows:

like foo

cc bb aa

I tried this for the word reverse on each line:

for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)

but if I want to print the return lines, I have to do this

 {a[NR]=$0 }END{for(i=NR; i; i--) print a[i]} 

I need to work with two files with this command in the terminal:

 awk -f commandFile FileToBePrinted 

The problem is that I begin in all of this, and I do not know how to combine these two. Thanks!

+7
source share
3 answers

Kev's decision considers reverse text in every word. You, for example, the conclusion, do not show this, but its key point is the use of the function.

You have the code you need, you just need to rebuild it a bit.

 cat file1 aa bb cc foo do as cat commandFile function reverse( line ) { n=split(line, tmpLine) for (j=n; j>0; j--) { printf("%s ",tmpLine[j] ) } } # main loop { a[NR]=$0 } # print reversed array END{ for(i=NR; i>0; i--) printf( "%s\n", reverse(a[i]) ) } 

Launch

  awk -f commandFile file1 

Exit

 as do foo cc bb aa 

There were a few minor changes that I made using n=split(line, tmpLine) ... print tmpLine[j] is a common method for parsing an input line in a function to print it. I don't think vars $ 1 has a region from the value passed from the array (your value [i]), so I changed it to split..tmpLine [j]. I also found that the variable "i" from the END section was stored in scope in the reverse function, so I changed it to j to fix this.


I had to figure out a few things, so the debug version that I used is presented below.

If you have access to gawk, it will be useful for you to learn how to use the debugger that is available. If you use awk / gawk / nawk on systems without a debugger, then this is one way to understand what is going on in your code. If you redirect your programs to a file or channel, And if the system supports the notation "/ dev / stderr", you can print debug lines there, i.e.

  #dbg print "#dbg0:line=" line > "/dev/stderr" 

Some systems have other designations for accessing stderr, so if you do so much, you should find out what is available.

 cat commandFile.debug function reverse( line ) { n=split(line, tmpLine) #dbg print "#dbg0:line=" line #dbg print "#dbg1:n=" n "\tj=" j "\ttmpLine[j]=" tmpLine[j] for (j=n; j>0; j--) { #dbg print "#dbg2:n=" n "\tj=" j "\ttempLine[j]=" tmpLine[j] printf("%s ",tmpLine[j] ) } } # main loop { a[NR]=$0 } # print reversed array #dbg END{ print "AT END"; for(i=NR; i>0; i--) printf( "#dbg4:i=%d\t%s\n%s\n", i, a[i] , reverse(a[i]) ) } END{ for(i=NR; i>0; i--) printf( "%s\n", reverse(a[i]) ) } 

Hope this helps.

+3
source
 awk ' { x=reverse($0) (x?"\n":"") x } END{ print x } function reverse(s, p) { for(i=length(s);i>0;i--) p=p substr(s,i,1) return p }' File1 
+2
source

use tac to flip lines of a file, then awk to reverse words.

 tac filename | awk '{for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)}' 

You can also use something like Perl that has built-in reverse functions:

 tac filename | perl -lane 'print join(" ", reverse(@F))' 
+2
source

All Articles