4

I have a list of hostnames in a file and want to separate them based on the last character. Write the host name to a file if the last character is odd number. How can I do this in one liner?

Example:

abc123
abc124
abc348
abc435

Desired output:

abc123
abc435
2

3 Answers 3

13

Short awk command:

awk '/[13579]$/' file > hostnames_odd.txt
  • [13579] - character class representing the list of allowed digits (odd numbers)
  • $ - the end of the string/line

Result:

$ cat hostnames_odd.txt 
abc123
abc435

Or the same with grep:

grep '[13579]$' file  > hostnames_odd.txt

In case if there could possibly be a whitespace(s) at the end of some line(s) change the crucial pattern to the following: [13579][[:space:]]*$

4
  • Why that print within awk? awk '/[13579]$/' file > hostnames_odd.txt seems more concise.
    – fedorqui
    Mar 22, 2018 at 10:51
  • @fedorqui, yes, we know that. For such simple case it would be enough (updated). But, in other case - the former is more scalable in case if we wanted to distribute lines on different files on some conditions like awk '/[13579]$/{ print > "hostnames_odd.txt" }/[02468]$/{ print > "hostnames_even.txt" }' file Mar 22, 2018 at 10:59
  • Why present the awk first? This is literally what grep was created for.
    – Kevin
    Mar 22, 2018 at 17:42
  • In order of overkill, probably grep first, then sed, then awk, then Perl @Kevin
    – Grump
    Mar 22, 2018 at 17:54
4

A tricky trick here: just set the field separator to an empty string, so that every single character is a field. This way, you just have to check if $NF is even or odd:

$ awk -F "" '$NF % 2' file
abc123
abc435

With other data:

$ echo "23
... 24
... 25" | awk -F "" '$NF % 2'
23
25
4
  • 1
    (with awk implementations that support that non-POSIX extension (many), awk -v FS= would be a bit more portable) Mar 22, 2018 at 10:52
  • @StéphaneChazelas oh thanks! Why is awk -v FS= more portable? What other implementations may we also get that wouldn't work with -F ""?
    – fedorqui
    Mar 22, 2018 at 10:58
  • 1
    Note , FS - If the value is the null string (""), then each character in the record becomes a separate field. (This behavior is a gawk extension. POSIX awk does not specify the behavior when FS is the null string. Nonetheless, some other versions of awk also treat "" specially.) Mar 22, 2018 at 11:06
  • See the link I provided. Mar 22, 2018 at 11:10
2

This will print out the lines read in if the last character mod 2 is not zero.

perl -wlne 'print $_ if ((substr $_, -1) % 2)' /path/to/file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .