I want to split a long text separated by spaces through bash, but I fail. The command below splits into characters, but not delimiters.
echo "The quick fox jumped over the lazy dog" | fold -w 10
echo "The quick fox jumped over the lazy dog" | sed -e 's/.\{9\}/&\n/g'It would be nice to have it for some user bash interaction.
Input syntax
format_text 10 "The quick fox jumped over the lazy dog"Output:
The quick
fox jumped
over the
lazy dogYou must notice that the third line would cut "l" letter from "lazy" off if not for spacing spacing rule.
Update: The current result is good, There is some issue with the work slicer I cannot get by myself: it does not break words before the limit is transpassed.
#!/bin/bash
printHeader () { declare -i line_length=$3 # Upper and lower fences local upper_command="print \"$1\" *" local upper_fence="$(python -c "$upper_command $line_length")" local lower_command="print \"$2\" *" local lower_fence="$(python -c "$lower_command $line_length")" # Slice words by some chracter counter local regex_counter="s/(.{$line_length}) /\1\n/g" # Complete line with dots and a pipe local res="$line_length - length" local repeat_pattern='$(repeat res \".\"; echo)' local fill_command="{res=($res); printf \"%s%s|\n\", $0, $repeat_pattern}" echo "$upper_fence" sed -r "$regex_counter" <<< $4 echo "$lower_fence"
}
printHeader "#" "#" 10 "The quick fox jumped over the lazy dog"Current output without final token:
##########
The quick fox
jumped over
the lazy dog
########## 5 1 Answer
sed -r 's/([^ .]+ [^ .]+) /\1\n/g' <<< "The quick fox jumped over the lazy dog"The quick
fox jumped
over the
lazy dogThe character set [^ .]+ means one or more + characters of any kind . excluding the ^ whitespaces. So the capture group ([^ .]+ [^ .]+) matches for patterns as string string. The whole regular expression has an additional whitespace at the end ([^ .]+ [^ .]+) (it could be included in the capture group in order to preserve it).
With sed by using the substitute s command we replace the matched pattern by the content of the first capture group \1 and a new line character \n instead of the whitespace. By the flag g we repeat the command to the end of each line. The -r option activates the extended regular expressions.
Update - this is the actual answer:
sed -r 's/(.{8}) /\1\n/g' <<< "How do we know it is going to match the pre-defined number of characters?"How do we
know it is
going to
match the
pre-defined
number of
characters?In this example we capture strings with length at least 8 characters (including whitespaces) followed by a whitespace. We can check the actual length of the output lines in a way as this:
sed -r 's/(.{8}) /\1\n/g' <<< "How do we know it is going to match the pre-defined number of characters?" \ | awk '{print length}'9
10
8
9
11
9
11And by the help of the answers of the question How to use printf to print a character multiple times? [awk] we can achieve the desired result.
sed -r 's/(.{8}) /\1\n/g' <<< "How do we know it is going to match the pre-defined number of characters?" \ | awk '{rest=(12 - length); printf "%s%s|\n", $0, substr(".........", 1, rest)}'How do we...|
know it is..|
going to....|
match the...|
pre-defined.|
number of...|
characters?.|In case you want to break the words remove the final whitespace from the above regular expression /(.{8})/. Here is an example where the max line length will be exactly 10 characters or less, where the second sed command will trim the whitespaces around each new line.
sed -r 's/(.{10})/\1\n/g' <<< "How do we know it is going to match the pre-defined number of characters?" \ | sed -r 's/(^ | $)//g' \ | awk '{rest=(10 - length); printf "%s%s|\n", $0, substr(".........", 1, rest)}'How do we.|
know it is|
going to..|
match the.|
pre-define|
d number o|
f characte|
rs?.......| 15