0

We have the following file:

cat info.txt

linux03.sys98.com net16777728       Speed: 1000Mb/s
linux03.sys98.com net16777728       Speed: 1000Mb/s
linux01.sys98.com net3f0    Speed: 1000Mb/s
linux01.sys98.com net3f0    Speed: 1000Mb/s

linux03.sys98.com net16777728       Duplex: Full
linux03.sys98.com net16777728       Duplex: Full
linux01.sys98.com net3f0    Duplex: Full
linux01.sys98.com net3f0    Duplex: Full

linux04.sys98.com net3f2    Link detected: no
linux04.sys98.com net3f3    Link detected: no

linux04.sys98.com net3f2    Speed: Unknown!
linux04.sys98.com net3f3    Speed: Unknown!

linux04.sys98.com net3f2    Duplex: Unknown! (255)
linux04.sys98.com net3f3    Duplex: Unknown! (255)

linux03.sys98.com net16777728       Link detected: yes
linux03.sys98.com net16777728       Link detected: yes
linux01.sys98.com net3f0    Link detected: yes
linux01.sys98.com net3f0    Link detected: yes

We want to align the third word with 20 spaces from the beginning of the second word as the following expected results:

linux03.sys98.com net16777728          Speed: 1000Mb/s
linux03.sys98.com net16777728          Speed: 1000Mb/s
linux01.sys98.com net3f0               Speed: 1000Mb/s
linux01.sys98.com net3f0               Speed: 1000Mb/s

linux03.sys98.com net16777728          Duplex: Full
linux03.sys98.com net16777728          Duplex: Full
linux01.sys98.com net3f0               Duplex: Full
linux01.sys98.com net3f0               Duplex: Full

linux04.sys98.com net3f2               Link detected: no
linux04.sys98.com net3f3               Link detected: no

linux04.sys98.com net3f2               Speed: Unknown!
linux04.sys98.com net3f3               Speed: Unknown!

linux04.sys98.com net3f2               Duplex: Unknown! (255)
linux04.sys98.com net3f3               Duplex: Unknown! (255)

linux03.sys98.com net16777728          Link detected: yes
linux03.sys98.com net16777728          Link detected: yes
linux01.sys98.com net3f0               Link detected: yes
linux01.sys98.com net3f0               Link detected: yes

How to perform that with printf or any other solution?

marked as duplicate by Kiwy, Thor, αғsнιη, Romeo Ninov, G-Man May 8 '18 at 5:10

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Are the two columns in the original file tab-delimited? – Kusalananda May 7 '18 at 14:22
  • no TAB delimited – jango May 7 '18 at 14:24
2

With perl:

perl -ne 'printf "%s %-20s %s\n", /(\S+\s+)(\S+)\s*(.*)/' your-file

Or to avoid touching lines that don't match that pattern:

perl -pe '$_ = sprintf "%s %-20s %s\n", $1, $2, $3
            if /(\S+\s+)(\S+)\s*(.*)/' your-file
  • was about to post a similar solution: perl -pe 's/(\H+\h+\H+)\h+/sprintf "%-39s", $1/e' .. only difference being mine would leave empty lines as is.. – Sundeep May 7 '18 at 14:32
  • another question please what in case we need to print dot "." between the second word to the third word then can you give example for that ? – jango May 7 '18 at 14:37
  • @jango, you can just add the . in the printf format (%s %-20s . %s). – Stéphane Chazelas May 7 '18 at 14:38
  • 1
    @Sundeep, good point about lines that don't match the pattern. See edit. – Stéphane Chazelas May 7 '18 at 14:39
2

With sed, you would add lots of spaces after the second field and then remove everything after the 20th char:

sed -E 's/([^ ]* ){2}/&                   /;s/( .{20}) */\1/'
0

With bash, you would write

while read a b rest; do
    printf "%s %-20s %s\n" "$a" "$b" "$rest"
done < info.txt

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