reverse print without trailing

1

I have a bash file calling a dns zone and have piped out the fqdn which I need to output in reverse.

The snippet below does that fine except I get a trialing . at the end which I don't want creating an import, csv (comma delimiter) format:

... | awk -F'.' '{for (i=NF;i>0;i--){printf $i"."};printf "\n"}' 

example source:

abc.def,ghi.com
hjd.dhjs.dhuj.oiuehj.ksjdhf.com

desired results:

com.ghi.def.abc
com.ksjdhf.oiuehj.dhuj.dhjs.hjd

current results:

com.ghi.def.abc.
com.ksjdhf.oiuehj.dhuj.dhjs.hjd.

carter

Posted 2014-10-15T22:36:35.253

Reputation: 25

Answers

2

Here is one approach:

awk -F'.' '{for (i=NF;i>1;i--){printf $i"."};print $1}' 

Sample usage:

$ echo abc.def.ghi.com | awk -F'.' '{for (i=NF;i>1;i--){printf $i"."};print $1}' 
com.ghi.def.abc

Explanation:

  • for (i=NF;i>1;i--){printf $i"."

    This prints the parts in reverse, starting at $NF and stopping at $2 (the second field), with each part followed by a period.

  • print $1

    This prints the final part without a trailing period. Because print is used here, rather than printf, there is no need for an explicit newline.

Alternative

For variety, here is another solution:

awk -F'.' '{s=""; for (i=NF;i>0;i--){s=s"."$i};print substr(s,2)}'

This uses the same logic as the original post: one loop over all parts. Rather than printing at each step, though, this saves the desired output into string s. At the end it prints s except for the last character which would be the superfluous period.

Alternative using tac rather than awk

$ echo abc.def.ghi.com | tr '.' '\n' | tac | tr '\n' '.' | sed 's/\.$/\n/'
com.ghi.def.abc

Or, even simpler:

$ echo  abc.def.ghi.com | tac -s'[.\n]' 
abc.def.ghi.com

John1024

Posted 2014-10-15T22:36:35.253

Reputation: 13 893

Any chance you can explain why $1 works over "\n"? – Michael Frank – 2014-10-15T22:49:26.800

1@MichaelFrank I updated the answer with some explanation. Briefly, the difference is that the loop stops at i==2. Thus, when the loop ends, $1 still needs to be printed and we print it without the superfluous trailing period. – John1024 – 2014-10-15T22:56:19.813

0

You can also use printf with another variable: the character to print after each field.

$ awk -F"[.,]" '{for (i=NF;i>0;i--) printf "%s%s", $i, (i==1?"\n":".")}' file
com.ghi.def.abc
com.ksjdhf.oiuehj.dhuj.dhjs.hjd
  • -F"[.,]" sets the field separator to either . or ,. This way, each single word will count as a different field.
  • (i==1?"\n":".") means: in case i is 1, then use \n; otherwise, use ..

fedorqui

Posted 2014-10-15T22:36:35.253

Reputation: 1 517