1

Please help me finding a solution to the below issue. I am trying to write a SINGLE LINE command in Linux which gives me the output (picture attached) from Example.txt file below -

Input - Example.txt

11430.00    SH: gry to dk gry, firm to mod hd, plty, flk, ea to gt, abd LCM; SLTST: gry, sft to firm, amor to blky, slty to ea
11460.00    SH: gry to dk gry, firm to mod hd, plty, flk, ea to gt, abd LCM; SLTST: gry, sft to firm, amor to blky, slty to ea
11490.00    MRL: lt gry, mod hd, blky, occ flk, wxy; SH: gry to dk gry, firm to mod hd, plty, occ blky, ea to gt; SLTST: gry to dk gry, mod firm to firm, amor, blky, slty
11520.00    SH: gry to dk gry, firm to mod hd, plty, blky, ea to gt, tr MRL, occ LCM; SLTST: gry, occ brnsh rd, firm, amor to blky, ea to g

I used fmt -w 50 -u Example.txt > FMT_Output.txt but does not generate a desired output. I need spaces/tabs on all lines except the ones that start with numbers like shown under Desired Output. I also tried using sed 's/^/ / command but it is a multi step process and this command does not give the desired output either. Can you please let me know if there is a way to do it in a single step process?

Output

Updated Question

Unfortunately it is not working when I try to load the formatted file. When I load the file, the system should realize the number as column 1 and text as column 2. But the entire formatted first line is getting into first column and remaining text on second column. Can you please think of a way to format based on column headers? Please see the new picture.

DEEP    Description
(ft)    -
12370.0 LS: Mdst, blsh gry, sft, occ mod firm, crpxln, prly, arg, SLTST: blk, firm-mod hd, amor, gt, mod calc, CLST: lt gry-m gry, sft, amor, wxy
12400.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg, SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, CLST: lt gry-m gry, occ rdsh gry, mod firm, amor, wxy, tr CHK
12430.0 LS: Mdst, blsh gry, mod firm, crpxln, chky, arg, SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, SH: blk-dk gry, mod firm, blky-plty, occ brit, wxy
12460.0 SH: blk-dk gry, mod firm, blky-plty, occ brit, ea, SLTST: blk-dk gry, firm-mod hd, amor, gt, mod calc, SST: gry-dk gry, wl consol, v f, ang, p srt, cotd, slily calc cmt, no fluor
2
  • Could you please post text. It's terribly tedious to type in the example input to try to test things... And also, is the a tab between the two columns, or a number of spaces?
    – Kusalananda
    Aug 28, 2017 at 14:26
  • Sure, I tried it before but I wasn't able to format the way it looks like in the picture. I posted the text but it looks like the format in the picture. I think there is a smaller tab.
    – NewCoder
    Aug 28, 2017 at 15:38

1 Answer 1

4

The par text formatter (and GNU sed) (see end for non-par solution):

$ tr -s ' ' <file.in | awk '{ print $0, "\n" }' | par 50p8h | sed -r -e '/^$/d' -e 's/^ {8}/\t/'
11430.00 SH: gry to dk gry, firm to mod hd, plty,
        flk, ea to gt, abd LCM; SLTST: gry, sft to
        firm, amor to blky, slty to ea
11460.00 SH: gry to dk gry, firm to mod hd, plty,
        flk, ea to gt, abd LCM; SLTST: gry, sft to
        firm, amor to blky, slty to ea
11490.00 MRL: lt gry, mod hd, blky, occ flk, wxy;
        SH: gry to dk gry, firm to mod hd, plty,
        occ blky, ea to gt; SLTST: gry to dk gry,
        mod firm to firm, amor, blky, slty
11520.00 SH: gry to dk gry, firm to mod hd, plty,
        blky, ea to gt, tr MRL, occ LCM; SLTST:
        gry, occ brnsh rd, firm, amor to blky, ea
        to g
  1. tr -s ' ' compresses multiple successive spaces into one.
  2. The awk code just adds an extra newline to each line of input.
  3. par 50p8h formats the resulting text to a width of 50 characters with 8 characters of hanging indent.
  4. The sed expressions deletes empty lines and replaces runs of 8 spaces at the start of a line with a single tab character.

For a solution that doesn't use GNU sed, you must insert a literal tab character in place of \t in the last sed expression.

For a solution that uses spaces for the indent and which aligns the left hanging indent exactly as in your screenshot (9 spaces in):

$ tr -s ' ' <file | awk '{ print $0, "\n" }' | par 50p9h | sed -e '/^$/d'
11430.00 SH: gry to dk gry, firm to mod hd, plty,
         flk, ea to gt, abd LCM; SLTST: gry, sft
         to firm, amor to blky, slty to ea
11460.00 SH: gry to dk gry, firm to mod hd, plty,
         flk, ea to gt, abd LCM; SLTST: gry, sft
         to firm, amor to blky, slty to ea
11490.00 MRL: lt gry, mod hd, blky, occ flk, wxy;
         SH: gry to dk gry, firm to mod hd, plty,
         occ blky, ea to gt; SLTST: gry to dk gry,
         mod firm to firm, amor, blky, slty
11520.00 SH: gry to dk gry, firm to mod hd, plty,
         blky, ea to gt, tr MRL, occ LCM; SLTST:
         gry, occ brnsh rd, firm, amor to blky, ea
         to g

Adding j to 50p9h will justify the paragraphs nicely:

11430.00 SH: gry to dk gry,  firm to mod hd, plty,
         flk, ea  to gt, abd LCM;  SLTST: gry, sft
         to firm, amor to blky, slty to ea
11460.00 SH: gry to dk gry,  firm to mod hd, plty,
         flk, ea  to gt, abd LCM;  SLTST: gry, sft
         to firm, amor to blky, slty to ea
11490.00 MRL: lt gry, mod  hd, blky, occ flk, wxy;
         SH: gry to dk gry,  firm to mod hd, plty,
         occ blky, ea to gt; SLTST: gry to dk gry,
         mod firm to firm, amor, blky, slty
11520.00 SH: gry to dk gry,  firm to mod hd, plty,
         blky, ea  to gt, tr MRL,  occ LCM; SLTST:
         gry, occ brnsh rd, firm, amor to blky, ea
         to g

... and adding l to that will force-justify the last line of each paragraph too (not as nice):

11430.00 SH: gry to dk gry,  firm to mod hd, plty,
         flk,  ea  to  gt, abd  LCM;  SLTST:  gry,
         sft  to firm,  amor to  blky, slty  to ea
11460.00 SH: gry to dk gry,  firm to mod hd, plty,
         flk,  ea  to  gt, abd  LCM;  SLTST:  gry,
         sft  to firm,  amor to  blky, slty  to ea
11490.00 MRL: lt gry, mod  hd, blky, occ flk, wxy;
         SH: gry to dk gry,  firm to mod hd, plty,
         occ  blky, ea  to  gt; SLTST:  gry to  dk
         gry, mod  firm to firm, amor,  blky, slty
11520.00 SH:   gry  to   dk  gry,   firm  to   mod
         hd,  plty,  blky,  ea   to  gt,  tr  MRL,
         occ   LCM;   SLTST:    gry,   occ   brnsh
         rd,  firm,   amor  to   blky,  ea   to  g

par is available from most package managers on most Unices, but you may also find its sources (to compile yourself) at http://www.nicemice.net/par/


Solution using fmt instead of par

$ tr -s ' ' <file.in | awk '{ print $0, "\n" }' | fmt -w 50 |
  awk '/^[^0-9]/  { $0 = "         " $0 }
                  { print }' | fmt -w 50 | sed '/^$/d'
11430.00 SH: gry to dk gry, firm to mod hd, plty,
         flk, ea to gt, abd LCM; SLTST: gry, sft
         to firm, amor to blky, slty to ea
11460.00 SH: gry to dk gry, firm to mod hd, plty,
         flk, ea to gt, abd LCM; SLTST: gry, sft
         to firm, amor to blky, slty to ea
11490.00 MRL: lt gry, mod hd, blky, occ flk, wxy;
         SH: gry to dk gry, firm to mod hd, plty,
         occ blky, ea to gt; SLTST: gry to dk gry,
         mod firm to firm, amor, blky, slty
11520.00 SH: gry to dk gry, firm to mod hd, plty,
         blky, ea to gt, tr MRL, occ LCM; SLTST:
         gry, occ brnsh rd, firm, amor to blky, ea
         to g

fmt is not as flexible in its formatting and here we need to use it twice to get the intended result. We also use the fact that each original line starts with a digit.

  1. tr -s ' ', as before.
  2. awk '{ print $0, "\n" }', as before.
  3. The first fmt call (fmt -w 50) is there to get the first line of each paragraph into the right width (50 characters).
  4. The awk script will indent each line that does not start with a digit by 9 spaces.
  5. The second fmt call will format the whole text to 50 characters, but now the indented lines will stay indented.
  6. The sed expression deletes empty lines.
10
  • Awesome, thanks for a very detailed answer. I get 'par: Command not found.' message when I execute the your solution. Can you please provide some insight to resolve that issue? I am executing this command on RHEL 6.
    – NewCoder
    Aug 26, 2017 at 5:25
  • @NewCoder You would have to install par using your ordinary package manager. If you're using yum, you should try yum install par. If you are unable to install a natively built package of par, you could download and compile it yourself from nicemice.net/par
    – Kusalananda
    Aug 26, 2017 at 6:22
  • ah okay. I am planning to pass on this script to a few users, unsure if they can install anything though. If you don't mind me asking, is there any other way to get this done without users having to install something? Thanks a lot for your time.
    – NewCoder
    Aug 26, 2017 at 15:23
  • @NewCoder Updated (see end).
    – Kusalananda
    Aug 26, 2017 at 15:52
  • Amazing, thanks a lot for your answer. Unfortunately, not all lines start with a number in the files I get, I will check if that will be a problem though.
    – NewCoder
    Aug 28, 2017 at 13:48

You must log in to answer this question.

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