Awk reverse both lines and words

别说谁变了你拦得住时间么 提交于 2019-12-05 05:08:25

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))'
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!