I'm new to programming language and stuff so I have to reverse with awk all the lines and as well all the words in those lines, from a file and print them out.
"File1" to reverse:
aa bb cc
foo do as
And the output printing of the "File1" should be this:
as do foo
cc bb aa
I tried this for word reverse in each line:
for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)
but if I want to print the reversed 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 terminal:
awk -f commandFile FileToBePrinted
The problem is I'm beginer in all this and I don't know how to combine those two. Thanks!
Kev's solution looks to reverse the text in each word. You example output doesn't show that, but his key point is to use a function.
You have the code you need, you just need to rearrange it a little.
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]) ) }
Running
awk -f commandFile file1
output
as do foo
cc bb aa
There were a couple of minor changes I made, using n=split(line, tmpLine) ... print tmpLine[j]
, is a common method of parsing a line of input in a function to print it out. I don't think the $1 vars have scope from a value passed in from an array (your a[i] value), so I changed it to split..tmpLine[j]. I also found that the 'i' variable from END section was kept in scope in the function reverse
, so I changed that to j to disambiguate the situation.
I had to figure out a few things, so below is the debug version that I used.
If you're going to have access to gawk, then you'll do well to learn how to use the debugger that is available. If you're using awk/gawk/nawk on systems without a debugger, then this is one method for understanding what is happening in your code. If you're redirecting your programs output to a file or pipe, AND if you system supports "/dev/stderr" notation, you could print the debug lines there, i.e.
#dbg print "#dbg0:line=" line > "/dev/stderr"
Some systems have other notations for accessing stderr, so if you'll be doing this much, it is worthwhile to 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]) ) }
I hope this helps.
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
use tac to reverse the lines of the file, then awk to reverse the words.
tac filename | awk '{for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)}'
You could also use something like Perl that has list-reversing functions built-in:
tac filename | perl -lane 'print join(" ", reverse(@F))'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With