1

I have file which has the following contents:

   foo-6-25.example.com:
         1  Var. Speed   System Board    Normal     Yes     Normal   ( 49)
    --
    foo-5-4.example.com:
         1  Var. Speed   System Board    Normal     Yes     Normal   ( 19)
    --
    foo-8-28.example.com:
         1  Var. Speed   System Board    Normal     Yes     Normal   ( 43)
    --
    foo-9-7.example.com:
         1  Var. Speed   System Board    Normal     Yes     Normal   ( 91)
    --
    foo-5-19.idmz.example.com:
         1  Var. Speed   System Board    Normal     Yes     Normal   ( 19)
    --
    foo-7-3.example.com:
         1  Var. Speed   System Board    Normal     Yes     Normal   ( 20)

I want to format it in the following way: servername and then its FAN speed which is inside () bracket

foo-6-25.example.com: ( 49)
foo-5-4.example.com:  ( 19)

Not sure how to use that using awk or any other tools.

2

awk solution

$ awk '/:/{d=$1}/Speed/{printf"%-28s%s\n",d,substr($0,length($0)-4)}' file
foo-6-25.example.com:       ( 49)
foo-5-4.example.com:        ( 19)
foo-8-28.example.com:       ( 43)
foo-9-7.example.com:        ( 91)
foo-5-19.idmz.example.com:  ( 19)
foo-7-3.example.com:        ( 20)
$

awk + column solution

Aligns the columns dynamically.

$ awk '/:/{d=$1}/Speed/{print d,substr($0,length($0)-4)}' file|column -to' '
foo-6-25.example.com:       ( 49)
foo-5-4.example.com:        ( 19)
foo-8-28.example.com:       ( 43)
foo-9-7.example.com:        ( 91)
foo-5-19.idmz.example.com:  ( 19)
foo-7-3.example.com:        ( 20)
$
5
  • 2
    you are just awesome!!! – Satish Aug 8 '18 at 22:54
  • 1
    I like your aws + column solution but in output i am seeing foo-8-1.example.com: ( 49) how do i reduce this space in ` ( look like tab space 49)` ? – Satish Aug 8 '18 at 22:55
  • column: illegal option -- o :( – Satish Aug 8 '18 at 23:10
  • 1
    nevermid my bad, i was on MacBookPro after moving my file on Linux it seems looking good – Satish Aug 8 '18 at 23:17
  • 1
    Damn!!! it you are the beast in awk take a bow!!! – Satish Aug 8 '18 at 23:22
1
$ sed -e '/--/d;N;s/\n/ /;s/[[:blank:]]\+//;s/[[:blank:]]\+[^(]\+/, /' file | column -ts ','
foo-6-25.example.com:        ( 49)
foo-5-4.example.com:         ( 19)
foo-8-28.example.com:        ( 43)
foo-9-7.example.com:         ( 91)
foo-5-19.idmz.example.com:   ( 19)
foo-7-3.example.com:         ( 20)

If you don't want any spacing/alignment of the 2nd column you can omit the column command:

$ sed -e '/--/d;N;s/\n/ /;s/[[:blank:]]\+//;s/[[:blank:]]\+[^(]\+/ /' file
foo-6-25.example.com: ( 49)
foo-5-4.example.com: ( 19)
foo-8-28.example.com: ( 43)
foo-9-7.example.com: ( 91)
foo-5-19.idmz.example.com: ( 19)
foo-7-3.example.com: ( 20)

If you're dealing with GNU sed you can reduce it further:

$ sed -e '/--/d;N;s/\n/ /;s/[ ]\+//;s/[ ]\+[^(]\+/ /' file
4
  • I have tired your solution but its printing everything in single like like foo-010101-5-4.example.com: 1 Var. Speed System Board Normal Yes Normal ( 19) – Satish Aug 8 '18 at 23:03
  • I suspect your output isn't just spaces as you're showing in the example data, is it? – slm Aug 8 '18 at 23:05
  • my file is correct and i am replacing file with my filename.txt – Satish Aug 8 '18 at 23:12
  • I showed this style of example b/c unlike the awk you can more easily add/remove portions of this solution to see how it's working. Each /../; block in the sed is doing something specific, you can take them all out and then add them back in 1 at a time to see how they work and work towards you solution rather than have to have a lot of knowledge about awk. – slm Aug 8 '18 at 23:13
1
% perl -ne 'print(($_ .= <>) =~ s/\n.*\(/ (/r) if /:/' input.file

outputs:

foo-6-25.example.com: ( 49)
foo-5-4.example.com: ( 19)
foo-8-28.example.com: ( 43)
foo-9-7.example.com: ( 91)
foo-5-19.idmz.example.com: ( 19)
foo-7-3.example.com: ( 20)

explanation:

  1. on a line comprising :, it appends the next line to the current record.
  2. then deletes from the newline of the original line till the last ( and replaces this with ( and prints the record.
  3. Since perl was invoked with -n, records not affected are not printed.

Sed has a very compact way to write the same:

sed -ne '/:/N;s/\n.*(/ (/p' input.file
0
< file perl -pe 's/\n//g;s/(foo)/\n$1/g' | perl -pe 's/:.*\(/: (/g'
0

Using awk in paragraph mode

awk -vRS='\n[ \t]*--' '
  match($0, /\( *[0-9]+\)/) {print $1, substr($0,RSTART,RLENGTH)}
' file
foo-6-25.example.com: ( 49)
foo-5-4.example.com: ( 19)
foo-8-28.example.com: ( 43)
foo-9-7.example.com: ( 91)
foo-5-19.idmz.example.com: ( 19)
foo-7-3.example.com: ( 20)
0
$ sed -nE '/:/{N;s/^[[:space:]]+//; s/:[^(]+/: /p;}' file
foo-6-25.example.com: ( 49)
foo-5-4.example.com: ( 19)
foo-8-28.example.com: ( 43)
foo-9-7.example.com: ( 91)
foo-5-19.idmz.example.com: ( 19)
foo-7-3.example.com: ( 20)

If there are no initial spaces or tabs on each line, then just

sed -nE '/:/{N;s/:[^(]+/: /p;}' file

The (first) sed script annotated (assumes -E and -n):

/:/{                    # this line contains a host name
    N;                  # append the next line from the input
    s/^[[:space:]]+//;  # remove the initial spaces or tabs
    s/:[^(]+/: /p;      # remove the bit between the ":" and "(" and print
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.