Wrap and indent text using coreutils

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP

up vote
6
down vote

favorite

1

Short version

I would like to create a tabular display of multiline text, similar to the following:

all       Build all targets
document  Create documentation of source files in the subfolders
          `src` and `script`, and write it to `man`
test      Run unit tests

At the moment, my input for this looks as follows, but this can of course be changed:

all---Build all targets
document---Create documentation of source files in the subfolders `src` and `script`, and write it to `man`
test---Run unit tests

I’ve tried achieving this with a combination of awk and wrap/pr but while the line wrapping works, the indentation doesn’t. Here’s my current approach:

…
| awk -F '---' "{ printf '%-10s %sn', $1, $2 }" 
| fold -w $(($COLUMNS - 1)) -s

It generates the output

all       Build all targets
document  Create documentation of source files in the subfolders
`src` and `script`, and write it to `man`
test      Run unit tests

… in other words, the third line isn’t indented as intended.

How can I format the text with a given wrap length and a given hanging indent width? — Without changing anything else about the text. Bonus: this should work with UTF-8 and escape/control characters.


Background info

The goal is to create self-documenting Makefiles. As a consequence, the logic to format and display the code should be small, self-contained, and not rely on separately installed software; ideally, it should work on any system that can execute Makefiles, hence my restriction to (something close to) coreutils.

That said, I briefly tried solving the problem using groff but this became too complex very quickly (and OS X groff is and old version that doesn’t seem to support UTF-8).

The original string that I’m trying to parse and format therefore looks rather as follows:

## Build all targets
all: test document

## Run unit tests
test:
    ./run-tests .

## create documentation of source files in the subfolders `src` and `script`,
## and write it to `man`
document:
    ${MAKE} -C src document
    ${MAKE} -C script document

At the moment, this is parsed using a sed script (see link for details) that ignores multiline comments, before being fed to the formatting code posted above.

share|improve this question

  • You should be able to write the whole script in awk (sed and fold do not really add to the solution).
    – Thomas Dickey
    Apr 30 ’16 at 13:04

  • @ThomasDickey Can awk easily wrap lines at whitespace? the regular expression and text manipulation tools of awk are rather primitive … short of manually implementing the word-wrapping inside a (nested) loop.
    – Konrad Rudolph
    Apr 30 ’16 at 13:27

  • awk can compute a length, determine the place to split a line and format a continuation line. Those are easier to do than sed and wrap (and if I were writing this sort of application, would make it more portable than you propose).
    – Thomas Dickey
    Apr 30 ’16 at 13:32

  • @ThomasDickey Replacing sed by awk is of course possible but (a) I need to have two separate commands because I sort the entries in-between parsing and formatting, and POSIX awk doesn’t have built-in sort (gawk does); and (b) simply extracting the documentation seems simpler in sed than awk.
    – Konrad Rudolph
    May 3 ’16 at 11:58

  • sort is not mentioned in the question..
    – Thomas Dickey
    May 3 ’16 at 12:17

up vote
6
down vote

favorite

1

Short version

I would like to create a tabular display of multiline text, similar to the following:

all       Build all targets
document  Create documentation of source files in the subfolders
          `src` and `script`, and write it to `man`
test      Run unit tests

At the moment, my input for this looks as follows, but this can of course be changed:

all---Build all targets
document---Create documentation of source files in the subfolders `src` and `script`, and write it to `man`
test---Run unit tests

I’ve tried achieving this with a combination of awk and wrap/pr but while the line wrapping works, the indentation doesn’t. Here’s my current approach:

…
| awk -F '---' "{ printf '%-10s %sn', $1, $2 }" 
| fold -w $(($COLUMNS - 1)) -s

It generates the output

all       Build all targets
document  Create documentation of source files in the subfolders
`src` and `script`, and write it to `man`
test      Run unit tests

… in other words, the third line isn’t indented as intended.

How can I format the text with a given wrap length and a given hanging indent width? — Without changing anything else about the text. Bonus: this should work with UTF-8 and escape/control characters.


Background info

The goal is to create self-documenting Makefiles. As a consequence, the logic to format and display the code should be small, self-contained, and not rely on separately installed software; ideally, it should work on any system that can execute Makefiles, hence my restriction to (something close to) coreutils.

That said, I briefly tried solving the problem using groff but this became too complex very quickly (and OS X groff is and old version that doesn’t seem to support UTF-8).

The original string that I’m trying to parse and format therefore looks rather as follows:

## Build all targets
all: test document

## Run unit tests
test:
    ./run-tests .

## create documentation of source files in the subfolders `src` and `script`,
## and write it to `man`
document:
    ${MAKE} -C src document
    ${MAKE} -C script document

At the moment, this is parsed using a sed script (see link for details) that ignores multiline comments, before being fed to the formatting code posted above.

share|improve this question

  • You should be able to write the whole script in awk (sed and fold do not really add to the solution).
    – Thomas Dickey
    Apr 30 ’16 at 13:04

  • @ThomasDickey Can awk easily wrap lines at whitespace? the regular expression and text manipulation tools of awk are rather primitive … short of manually implementing the word-wrapping inside a (nested) loop.
    – Konrad Rudolph
    Apr 30 ’16 at 13:27

  • awk can compute a length, determine the place to split a line and format a continuation line. Those are easier to do than sed and wrap (and if I were writing this sort of application, would make it more portable than you propose).
    – Thomas Dickey
    Apr 30 ’16 at 13:32

  • @ThomasDickey Replacing sed by awk is of course possible but (a) I need to have two separate commands because I sort the entries in-between parsing and formatting, and POSIX awk doesn’t have built-in sort (gawk does); and (b) simply extracting the documentation seems simpler in sed than awk.
    – Konrad Rudolph
    May 3 ’16 at 11:58

  • sort is not mentioned in the question..
    – Thomas Dickey
    May 3 ’16 at 12:17

up vote
6
down vote

favorite

1

up vote
6
down vote

favorite

1
1

Short version

I would like to create a tabular display of multiline text, similar to the following:

all       Build all targets
document  Create documentation of source files in the subfolders
          `src` and `script`, and write it to `man`
test      Run unit tests

At the moment, my input for this looks as follows, but this can of course be changed:

all---Build all targets
document---Create documentation of source files in the subfolders `src` and `script`, and write it to `man`
test---Run unit tests

I’ve tried achieving this with a combination of awk and wrap/pr but while the line wrapping works, the indentation doesn’t. Here’s my current approach:

…
| awk -F '---' "{ printf '%-10s %sn', $1, $2 }" 
| fold -w $(($COLUMNS - 1)) -s

It generates the output

all       Build all targets
document  Create documentation of source files in the subfolders
`src` and `script`, and write it to `man`
test      Run unit tests

… in other words, the third line isn’t indented as intended.

How can I format the text with a given wrap length and a given hanging indent width? — Without changing anything else about the text. Bonus: this should work with UTF-8 and escape/control characters.


Background info

The goal is to create self-documenting Makefiles. As a consequence, the logic to format and display the code should be small, self-contained, and not rely on separately installed software; ideally, it should work on any system that can execute Makefiles, hence my restriction to (something close to) coreutils.

That said, I briefly tried solving the problem using groff but this became too complex very quickly (and OS X groff is and old version that doesn’t seem to support UTF-8).

The original string that I’m trying to parse and format therefore looks rather as follows:

## Build all targets
all: test document

## Run unit tests
test:
    ./run-tests .

## create documentation of source files in the subfolders `src` and `script`,
## and write it to `man`
document:
    ${MAKE} -C src document
    ${MAKE} -C script document

At the moment, this is parsed using a sed script (see link for details) that ignores multiline comments, before being fed to the formatting code posted above.

share|improve this question

Short version

I would like to create a tabular display of multiline text, similar to the following:

all       Build all targets
document  Create documentation of source files in the subfolders
          `src` and `script`, and write it to `man`
test      Run unit tests

At the moment, my input for this looks as follows, but this can of course be changed:

all---Build all targets
document---Create documentation of source files in the subfolders `src` and `script`, and write it to `man`
test---Run unit tests

I’ve tried achieving this with a combination of awk and wrap/pr but while the line wrapping works, the indentation doesn’t. Here’s my current approach:

…
| awk -F '---' "{ printf '%-10s %sn', $1, $2 }" 
| fold -w $(($COLUMNS - 1)) -s

It generates the output

all       Build all targets
document  Create documentation of source files in the subfolders
`src` and `script`, and write it to `man`
test      Run unit tests

… in other words, the third line isn’t indented as intended.

How can I format the text with a given wrap length and a given hanging indent width? — Without changing anything else about the text. Bonus: this should work with UTF-8 and escape/control characters.


Background info

The goal is to create self-documenting Makefiles. As a consequence, the logic to format and display the code should be small, self-contained, and not rely on separately installed software; ideally, it should work on any system that can execute Makefiles, hence my restriction to (something close to) coreutils.

That said, I briefly tried solving the problem using groff but this became too complex very quickly (and OS X groff is and old version that doesn’t seem to support UTF-8).

The original string that I’m trying to parse and format therefore looks rather as follows:

## Build all targets
all: test document

## Run unit tests
test:
    ./run-tests .

## create documentation of source files in the subfolders `src` and `script`,
## and write it to `man`
document:
    ${MAKE} -C src document
    ${MAKE} -C script document

At the moment, this is parsed using a sed script (see link for details) that ignores multiline comments, before being fed to the formatting code posted above.

text-processing make text-formatting coreutils fold

share|improve this question

share|improve this question

share|improve this question

share|improve this question

edited Dec 6 at 17:30

Jeff Schaller

37.9k1053123

37.9k1053123

asked Apr 30 ’16 at 12:56

Konrad Rudolph

2,08231222

2,08231222

  • You should be able to write the whole script in awk (sed and fold do not really add to the solution).
    – Thomas Dickey
    Apr 30 ’16 at 13:04

  • @ThomasDickey Can awk easily wrap lines at whitespace? the regular expression and text manipulation tools of awk are rather primitive … short of manually implementing the word-wrapping inside a (nested) loop.
    – Konrad Rudolph
    Apr 30 ’16 at 13:27

  • awk can compute a length, determine the place to split a line and format a continuation line. Those are easier to do than sed and wrap (and if I were writing this sort of application, would make it more portable than you propose).
    – Thomas Dickey
    Apr 30 ’16 at 13:32

  • @ThomasDickey Replacing sed by awk is of course possible but (a) I need to have two separate commands because I sort the entries in-between parsing and formatting, and POSIX awk doesn’t have built-in sort (gawk does); and (b) simply extracting the documentation seems simpler in sed than awk.
    – Konrad Rudolph
    May 3 ’16 at 11:58

  • sort is not mentioned in the question..
    – Thomas Dickey
    May 3 ’16 at 12:17

  • You should be able to write the whole script in awk (sed and fold do not really add to the solution).
    – Thomas Dickey
    Apr 30 ’16 at 13:04

  • @ThomasDickey Can awk easily wrap lines at whitespace? the regular expression and text manipulation tools of awk are rather primitive … short of manually implementing the word-wrapping inside a (nested) loop.
    – Konrad Rudolph
    Apr 30 ’16 at 13:27

  • awk can compute a length, determine the place to split a line and format a continuation line. Those are easier to do than sed and wrap (and if I were writing this sort of application, would make it more portable than you propose).
    – Thomas Dickey
    Apr 30 ’16 at 13:32

  • @ThomasDickey Replacing sed by awk is of course possible but (a) I need to have two separate commands because I sort the entries in-between parsing and formatting, and POSIX awk doesn’t have built-in sort (gawk does); and (b) simply extracting the documentation seems simpler in sed than awk.
    – Konrad Rudolph
    May 3 ’16 at 11:58

  • sort is not mentioned in the question..
    – Thomas Dickey
    May 3 ’16 at 12:17

You should be able to write the whole script in awk (sed and fold do not really add to the solution).
– Thomas Dickey
Apr 30 ’16 at 13:04

You should be able to write the whole script in awk (sed and fold do not really add to the solution).
– Thomas Dickey
Apr 30 ’16 at 13:04

@ThomasDickey Can awk easily wrap lines at whitespace? the regular expression and text manipulation tools of awk are rather primitive … short of manually implementing the word-wrapping inside a (nested) loop.
– Konrad Rudolph
Apr 30 ’16 at 13:27

@ThomasDickey Can awk easily wrap lines at whitespace? the regular expression and text manipulation tools of awk are rather primitive … short of manually implementing the word-wrapping inside a (nested) loop.
– Konrad Rudolph
Apr 30 ’16 at 13:27

awk can compute a length, determine the place to split a line and format a continuation line. Those are easier to do than sed and wrap (and if I were writing this sort of application, would make it more portable than you propose).
– Thomas Dickey
Apr 30 ’16 at 13:32

awk can compute a length, determine the place to split a line and format a continuation line. Those are easier to do than sed and wrap (and if I were writing this sort of application, would make it more portable than you propose).
– Thomas Dickey
Apr 30 ’16 at 13:32

@ThomasDickey Replacing sed by awk is of course possible but (a) I need to have two separate commands because I sort the entries in-between parsing and formatting, and POSIX awk doesn’t have built-in sort (gawk does); and (b) simply extracting the documentation seems simpler in sed than awk.
– Konrad Rudolph
May 3 ’16 at 11:58

@ThomasDickey Replacing sed by awk is of course possible but (a) I need to have two separate commands because I sort the entries in-between parsing and formatting, and POSIX awk doesn’t have built-in sort (gawk does); and (b) simply extracting the documentation seems simpler in sed than awk.
– Konrad Rudolph
May 3 ’16 at 11:58

sort is not mentioned in the question..
– Thomas Dickey
May 3 ’16 at 12:17

sort is not mentioned in the question..
– Thomas Dickey
May 3 ’16 at 12:17

3 Answers
3

active

oldest

votes

up vote
4
down vote

accepted

With gnu awk you can do something simple like this:

awk -F '---' '
{ gsub(/.{50,60} /,"&n           ",$2)
  printf "%-10s %sn", $1, $2 }'

For a more accurate long-winded version handling long words:

awk -F '---' '
{ printf "%-10s ", $1
  n = split($2,x," ")
  len = 11
  for(i=1;i<=n;i++){
   if(len+length(x[i])>=80){printf "n           "; len = 11}
   printf "%s ",x[i]
   len += 1+length(x[i])
  }
  printf "n"
}'

share|improve this answer

  • This is almost perfect. The only problem is that the lower bound — 50 — is arbitrary and will break if the input contains a word with more than 10 characters at the crucial position. Any suggestion for how to fix this? Using a lower number won’t work because then the match seems to happen non-greedily (actually I’m not sure what’s happening because it’s not simply matching single words).
    – Konrad Rudolph
    Apr 30 ’16 at 14:46

  • Yes long words are a problem for this simple code. I added some more laborious handling for better results.
    – meuh
    Apr 30 ’16 at 15:57

  • Ah hm. I was precisely trying to avoid that and use a pre-baked solution instead to handle edge cases properly: for instance, the above doesn’t handle dashes nicely — but, it turns out, neither does fold. So I’ll go with this.
    – Konrad Rudolph
    May 3 ’16 at 11:22

  • I believe that this is not specific to GNU AWK, testing it on a fresh FreeBSD installation with no GNU utilities, I get the desired output.
    – forquare
    May 3 ’16 at 12:26

up vote
3
down vote

Here’s a shorter answer that uses fold then shifts its output by 11 spaces.
To see what it is doing add a -v or -x to the final bash.

| sed 's:(.*)---(.*):printf "%-10s " "1";fold -w '$(($COLUMNS - 11))' -s <<\!|sed "1!s/^/           /"n2n!n:' | bash 

share|improve this answer

    up vote
    2
    down vote

    After the fold command pipe the output to sed and replace the start of line with a tab. And you can control the indent with with the ‘tabs ‘ command prior:

    tabs 5
    echo "A very long line that I want to fold on the word boundary and indent as well" | fold -s -w 20  | sed -e "s|^|t|g"
    
         A very long line
         that I want to fold
         on the word
         boundary and indent
         as well
    

    share|improve this answer

      Your Answer

      StackExchange.ready(function() {
      var channelOptions = {
      tags: “”.split(” “),
      id: “106”
      };
      initTagRenderer(“”.split(” “), “”.split(” “), channelOptions);

      StackExchange.using(“externalEditor”, function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using(“snippets”, function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: ‘answer’,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: “”,
      imageUploader: {
      brandingHtml: “Powered by u003ca class=”icon-imgur-white” href=”https://imgur.com/”u003eu003c/au003e”,
      contentPolicyHtml: “User contributions licensed under u003ca href=”https://creativecommons.org/licenses/by-sa/3.0/”u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href=”https://stackoverflow.com/legal/content-policy”u003e(content policy)u003c/au003e”,
      allowUrls: true
      },
      onDemand: true,
      discardSelector: “.discard-answer”
      ,immediatelyShowMarkdownHelp:true
      });

      }
      });

      draft saved
      draft discarded

      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin(‘.new-post-login’, ‘https%3a%2f%2funix.stackexchange.com%2fquestions%2f280199%2fwrap-and-indent-text-using-coreutils%23new-answer’, ‘question_page’);
      }
      );

      Post as a guest

      Required, but never shown

      3 Answers
      3

      active

      oldest

      votes

      3 Answers
      3

      active

      oldest

      votes

      active

      oldest

      votes

      active

      oldest

      votes

      up vote
      4
      down vote

      accepted

      With gnu awk you can do something simple like this:

      awk -F '---' '
      { gsub(/.{50,60} /,"&n           ",$2)
        printf "%-10s %sn", $1, $2 }'
      

      For a more accurate long-winded version handling long words:

      awk -F '---' '
      { printf "%-10s ", $1
        n = split($2,x," ")
        len = 11
        for(i=1;i<=n;i++){
         if(len+length(x[i])>=80){printf "n           "; len = 11}
         printf "%s ",x[i]
         len += 1+length(x[i])
        }
        printf "n"
      }'
      

      share|improve this answer

      • This is almost perfect. The only problem is that the lower bound — 50 — is arbitrary and will break if the input contains a word with more than 10 characters at the crucial position. Any suggestion for how to fix this? Using a lower number won’t work because then the match seems to happen non-greedily (actually I’m not sure what’s happening because it’s not simply matching single words).
        – Konrad Rudolph
        Apr 30 ’16 at 14:46

      • Yes long words are a problem for this simple code. I added some more laborious handling for better results.
        – meuh
        Apr 30 ’16 at 15:57

      • Ah hm. I was precisely trying to avoid that and use a pre-baked solution instead to handle edge cases properly: for instance, the above doesn’t handle dashes nicely — but, it turns out, neither does fold. So I’ll go with this.
        – Konrad Rudolph
        May 3 ’16 at 11:22

      • I believe that this is not specific to GNU AWK, testing it on a fresh FreeBSD installation with no GNU utilities, I get the desired output.
        – forquare
        May 3 ’16 at 12:26

      up vote
      4
      down vote

      accepted

      With gnu awk you can do something simple like this:

      awk -F '---' '
      { gsub(/.{50,60} /,"&n           ",$2)
        printf "%-10s %sn", $1, $2 }'
      

      For a more accurate long-winded version handling long words:

      awk -F '---' '
      { printf "%-10s ", $1
        n = split($2,x," ")
        len = 11
        for(i=1;i<=n;i++){
         if(len+length(x[i])>=80){printf "n           "; len = 11}
         printf "%s ",x[i]
         len += 1+length(x[i])
        }
        printf "n"
      }'
      

      share|improve this answer

      • This is almost perfect. The only problem is that the lower bound — 50 — is arbitrary and will break if the input contains a word with more than 10 characters at the crucial position. Any suggestion for how to fix this? Using a lower number won’t work because then the match seems to happen non-greedily (actually I’m not sure what’s happening because it’s not simply matching single words).
        – Konrad Rudolph
        Apr 30 ’16 at 14:46

      • Yes long words are a problem for this simple code. I added some more laborious handling for better results.
        – meuh
        Apr 30 ’16 at 15:57

      • Ah hm. I was precisely trying to avoid that and use a pre-baked solution instead to handle edge cases properly: for instance, the above doesn’t handle dashes nicely — but, it turns out, neither does fold. So I’ll go with this.
        – Konrad Rudolph
        May 3 ’16 at 11:22

      • I believe that this is not specific to GNU AWK, testing it on a fresh FreeBSD installation with no GNU utilities, I get the desired output.
        – forquare
        May 3 ’16 at 12:26

      up vote
      4
      down vote

      accepted

      up vote
      4
      down vote

      accepted

      With gnu awk you can do something simple like this:

      awk -F '---' '
      { gsub(/.{50,60} /,"&n           ",$2)
        printf "%-10s %sn", $1, $2 }'
      

      For a more accurate long-winded version handling long words:

      awk -F '---' '
      { printf "%-10s ", $1
        n = split($2,x," ")
        len = 11
        for(i=1;i<=n;i++){
         if(len+length(x[i])>=80){printf "n           "; len = 11}
         printf "%s ",x[i]
         len += 1+length(x[i])
        }
        printf "n"
      }'
      

      share|improve this answer

      With gnu awk you can do something simple like this:

      awk -F '---' '
      { gsub(/.{50,60} /,"&n           ",$2)
        printf "%-10s %sn", $1, $2 }'
      

      For a more accurate long-winded version handling long words:

      awk -F '---' '
      { printf "%-10s ", $1
        n = split($2,x," ")
        len = 11
        for(i=1;i<=n;i++){
         if(len+length(x[i])>=80){printf "n           "; len = 11}
         printf "%s ",x[i]
         len += 1+length(x[i])
        }
        printf "n"
      }'
      

      share|improve this answer

      share|improve this answer

      share|improve this answer

      edited Apr 30 ’16 at 15:56

      answered Apr 30 ’16 at 13:28

      meuh

      31.4k11754

      31.4k11754

      • This is almost perfect. The only problem is that the lower bound — 50 — is arbitrary and will break if the input contains a word with more than 10 characters at the crucial position. Any suggestion for how to fix this? Using a lower number won’t work because then the match seems to happen non-greedily (actually I’m not sure what’s happening because it’s not simply matching single words).
        – Konrad Rudolph
        Apr 30 ’16 at 14:46

      • Yes long words are a problem for this simple code. I added some more laborious handling for better results.
        – meuh
        Apr 30 ’16 at 15:57

      • Ah hm. I was precisely trying to avoid that and use a pre-baked solution instead to handle edge cases properly: for instance, the above doesn’t handle dashes nicely — but, it turns out, neither does fold. So I’ll go with this.
        – Konrad Rudolph
        May 3 ’16 at 11:22

      • I believe that this is not specific to GNU AWK, testing it on a fresh FreeBSD installation with no GNU utilities, I get the desired output.
        – forquare
        May 3 ’16 at 12:26

      • This is almost perfect. The only problem is that the lower bound — 50 — is arbitrary and will break if the input contains a word with more than 10 characters at the crucial position. Any suggestion for how to fix this? Using a lower number won’t work because then the match seems to happen non-greedily (actually I’m not sure what’s happening because it’s not simply matching single words).
        – Konrad Rudolph
        Apr 30 ’16 at 14:46

      • Yes long words are a problem for this simple code. I added some more laborious handling for better results.
        – meuh
        Apr 30 ’16 at 15:57

      • Ah hm. I was precisely trying to avoid that and use a pre-baked solution instead to handle edge cases properly: for instance, the above doesn’t handle dashes nicely — but, it turns out, neither does fold. So I’ll go with this.
        – Konrad Rudolph
        May 3 ’16 at 11:22

      • I believe that this is not specific to GNU AWK, testing it on a fresh FreeBSD installation with no GNU utilities, I get the desired output.
        – forquare
        May 3 ’16 at 12:26

      This is almost perfect. The only problem is that the lower bound — 50 — is arbitrary and will break if the input contains a word with more than 10 characters at the crucial position. Any suggestion for how to fix this? Using a lower number won’t work because then the match seems to happen non-greedily (actually I’m not sure what’s happening because it’s not simply matching single words).
      – Konrad Rudolph
      Apr 30 ’16 at 14:46

      This is almost perfect. The only problem is that the lower bound — 50 — is arbitrary and will break if the input contains a word with more than 10 characters at the crucial position. Any suggestion for how to fix this? Using a lower number won’t work because then the match seems to happen non-greedily (actually I’m not sure what’s happening because it’s not simply matching single words).
      – Konrad Rudolph
      Apr 30 ’16 at 14:46

      Yes long words are a problem for this simple code. I added some more laborious handling for better results.
      – meuh
      Apr 30 ’16 at 15:57

      Yes long words are a problem for this simple code. I added some more laborious handling for better results.
      – meuh
      Apr 30 ’16 at 15:57

      Ah hm. I was precisely trying to avoid that and use a pre-baked solution instead to handle edge cases properly: for instance, the above doesn’t handle dashes nicely — but, it turns out, neither does fold. So I’ll go with this.
      – Konrad Rudolph
      May 3 ’16 at 11:22

      Ah hm. I was precisely trying to avoid that and use a pre-baked solution instead to handle edge cases properly: for instance, the above doesn’t handle dashes nicely — but, it turns out, neither does fold. So I’ll go with this.
      – Konrad Rudolph
      May 3 ’16 at 11:22

      I believe that this is not specific to GNU AWK, testing it on a fresh FreeBSD installation with no GNU utilities, I get the desired output.
      – forquare
      May 3 ’16 at 12:26

      I believe that this is not specific to GNU AWK, testing it on a fresh FreeBSD installation with no GNU utilities, I get the desired output.
      – forquare
      May 3 ’16 at 12:26

      up vote
      3
      down vote

      Here’s a shorter answer that uses fold then shifts its output by 11 spaces.
      To see what it is doing add a -v or -x to the final bash.

      | sed 's:(.*)---(.*):printf "%-10s " "1";fold -w '$(($COLUMNS - 11))' -s <<\!|sed "1!s/^/           /"n2n!n:' | bash 
      

      share|improve this answer

        up vote
        3
        down vote

        Here’s a shorter answer that uses fold then shifts its output by 11 spaces.
        To see what it is doing add a -v or -x to the final bash.

        | sed 's:(.*)---(.*):printf "%-10s " "1";fold -w '$(($COLUMNS - 11))' -s <<\!|sed "1!s/^/           /"n2n!n:' | bash 
        

        share|improve this answer

          up vote
          3
          down vote

          up vote
          3
          down vote

          Here’s a shorter answer that uses fold then shifts its output by 11 spaces.
          To see what it is doing add a -v or -x to the final bash.

          | sed 's:(.*)---(.*):printf "%-10s " "1";fold -w '$(($COLUMNS - 11))' -s <<\!|sed "1!s/^/           /"n2n!n:' | bash 
          

          share|improve this answer

          Here’s a shorter answer that uses fold then shifts its output by 11 spaces.
          To see what it is doing add a -v or -x to the final bash.

          | sed 's:(.*)---(.*):printf "%-10s " "1";fold -w '$(($COLUMNS - 11))' -s <<\!|sed "1!s/^/           /"n2n!n:' | bash 
          

          share|improve this answer

          share|improve this answer

          share|improve this answer

          answered May 3 ’16 at 12:08

          meuh

          31.4k11754

          31.4k11754

              up vote
              2
              down vote

              After the fold command pipe the output to sed and replace the start of line with a tab. And you can control the indent with with the ‘tabs ‘ command prior:

              tabs 5
              echo "A very long line that I want to fold on the word boundary and indent as well" | fold -s -w 20  | sed -e "s|^|t|g"
              
                   A very long line
                   that I want to fold
                   on the word
                   boundary and indent
                   as well
              

              share|improve this answer

                up vote
                2
                down vote

                After the fold command pipe the output to sed and replace the start of line with a tab. And you can control the indent with with the ‘tabs ‘ command prior:

                tabs 5
                echo "A very long line that I want to fold on the word boundary and indent as well" | fold -s -w 20  | sed -e "s|^|t|g"
                
                     A very long line
                     that I want to fold
                     on the word
                     boundary and indent
                     as well
                

                share|improve this answer

                  up vote
                  2
                  down vote

                  up vote
                  2
                  down vote

                  After the fold command pipe the output to sed and replace the start of line with a tab. And you can control the indent with with the ‘tabs ‘ command prior:

                  tabs 5
                  echo "A very long line that I want to fold on the word boundary and indent as well" | fold -s -w 20  | sed -e "s|^|t|g"
                  
                       A very long line
                       that I want to fold
                       on the word
                       boundary and indent
                       as well
                  

                  share|improve this answer

                  After the fold command pipe the output to sed and replace the start of line with a tab. And you can control the indent with with the ‘tabs ‘ command prior:

                  tabs 5
                  echo "A very long line that I want to fold on the word boundary and indent as well" | fold -s -w 20  | sed -e "s|^|t|g"
                  
                       A very long line
                       that I want to fold
                       on the word
                       boundary and indent
                       as well
                  

                  share|improve this answer

                  share|improve this answer

                  share|improve this answer

                  answered Jun 22 ’17 at 18:40

                  Brandon Haberfeld

                  211

                  211

                      draft saved
                      draft discarded

                      Thanks for contributing an answer to Unix & Linux Stack Exchange!

                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid

                      • Asking for help, clarification, or responding to other answers.
                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.

                      Some of your past answers have not been well-received, and you’re in danger of being blocked from answering.

                      Please pay close attention to the following guidance:

                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid

                      • Asking for help, clarification, or responding to other answers.
                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.

                      draft saved

                      draft discarded

                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin(‘.new-post-login’, ‘https%3a%2f%2funix.stackexchange.com%2fquestions%2f280199%2fwrap-and-indent-text-using-coreutils%23new-answer’, ‘question_page’);
                      }
                      );

                      Post as a guest

                      Required, but never shown

                      Required, but never shown

                      Required, but never shown

                      Required, but never shown

                      Required, but never shown

                      Required, but never shown

                      Required, but never shown

                      Required, but never shown

                      Required, but never shown

                      Related Post

                      Leave a Reply

                      Your email address will not be published. Required fields are marked *