ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
can someone help me compose or develop a command line for a bash-script that will wrap a given expression from "$1" before a given line-limit and at a given delimiter? I have done a lot of experimenting with cut -c and -f and tr to insert line-breaks, for-loops with expr() to break the expression into lines. There have been good results, but some texts just would not be formatted correctly for my uses. The main problem is probably my abstinence from sed.
So the given initial values shall be those in the following example and what I am lacking is the intelligence to make the remainder of the script run correctly.
Code:
expression="$1"
delimiter="$2"
limit="$3"
if [ "$delimiter" == ' ' ]
then
delimiter=' '
fi
if [ "$limit" == ' ' ]
then
limit=40
fi
# ATTN! no call to sed below this line
# -----------------------------------
# Thank Youhou.
(...)
For the time, I call from my shell-scripts a small c++ program which does the wrapping, mainly to ensure that text of arbitrary origin is wrapped in a yad generated text-info box.
Otherwise, it is necessary to scroll, and sometimes a long way, to the right of the yad-dialog.
I feel, that the call to the binary “wrap-tool” is a little exaggerated. C/C++ code attached.
Last edited by Michael Uplawski; 08-16-2016 at 12:28 AM.
Reason: expr is not a good variable. Call it expression. Orthography... clarifying additions.
#!/usr/bin/env bash
expression="$1"
(( $# >= 2 )) && delimiter="$2" || delimiter=' '
(( $# == 3 )) && limit="$3" || limit=40
# Split data based on delimiter value
IFS="$delimiter"
output=( $expression )
unset IFS
# Only output length of line based on limit
for line in "${output[@]}"
do
while (( ${#line} > limit ))
do
echo "${line:0:limit}"
line="${line:limit}"
done
echo $line
done
There are some edge cases you would need to allow for and probably some other error checking at the start, but it should give you an idea
There are some edge cases you would need to allow for and probably some other error checking at the start, but it should give you an idea
This is good stuff!
All the elements are there and I do not spot a single ‘sed’.
But I have to admit, that it does the thing “the wrong way around”, probably because of my clumsy description, above. Do not worry, though. Your example motivates me to adapt it to my needs.
Just to show you what I have failed to explain, an example string, processed “both ways”:
Code:
This shall be a longer line of text, athough, ... wait, better this: "Oh but I was so much older then, I'm younger than that now"
If I call your script on the text, I get:
Code:
user@machine:/tmp$ ./wrap_sh "This shall be a longer line of text, although, ... wait, better this: \"Oh but I was so much older then, I'm younger than that now\"" " " 10
This
shall
be
a
longer
line
of
text,
although,
...
wait,
better
this:
"Oh
but
I
was
so
much
older
then,
I'm
younger
than
that
now"
Now the same with my incredibly marvelous wrap-tool:
Code:
user@machine:/tmp$ wrap "This shall be a longer line of text, although, ... wait, better this: \"Oh but I was so much older then, I'm younger than that now\"" " " 10
This shall
be a longer
line of
text, although,
... wait,
better
this: "Oh
but I was
so much
older then,
I'm younger
than that
now"
The difference is that a line-break does always replace a blank, but never before the indicated line-length (10). <-- This phrase is missing from my first post. Worse! I wrote “before a given line-limit”, meaning, that the line must be limited to some upper value, although readability requires that it be wrapped “after a minimum line-length”. The given line-limit is not the third parameter to the script, but the lateral limit of a graphical text box. Sorry.
Last edited by Michael Uplawski; 08-13-2016 at 06:13 AM.
Reason: post, not posting. Worse.
A first working script, not yet thoroughly tested but it produces the same result as the C++-tool from the example-string in the previous post.
Code:
#!/usr/bin/env bash
expression="$1"
(( $# >= 2 )) && delimiter="$2" || delimiter=' '
(( $# == 3 )) && limit="$3" || limit=40
# Split data based on delimiter value
IFS="$delimiter"
output=( $expression )
unset IFS
# Only output length of line based on limit
out=''
fraction=''
for line in "${output[@]}"
do
#echo "fraction is $fraction (${#fraction})"
if [ ${#fraction} -lt $limit ]
then
fraction="$fraction$delimiter$line"
else
out="$out$fraction"
fraction="\n$line"
fi
done
out="$out$fraction"
echo -e "${out:1}"
What bugs me still is the repeated line out="$out$fraction". A footer-controlled loop (do...while) is needed and I will lookup the shell-syntax, once my connection speed is up again (linuxquestions.org is one of the few sites that always charge quickly).
Probably [SOLVED] and thanks again.
Ah. Wait. I want to mention, that an alternative approach comprised a $(expr ${#out} % $limit) and I still consider the idea worth some thinking... but alas! It caused some headache, instead.
And... (edit II). Looking at this script solution, I wonder again, if I should not just stick with my wrap-tool anyway.
Last edited by Michael Uplawski; 08-13-2016 at 07:37 AM.
Reason: Modulo. Doubt.
awk, sed, perl or other can probably do this in a cleaner way, but the bash challenge is still a nice solution. I am not sure on the reason for a delimiter if you are going to then ignore it by saying the
limit is the overriding factor. It is probably that I do not understand the real intention of the code or if the delimiter is actually important, maybe just switch the order so length transition is performed first??
Ultimately, if you have a tool that works and no need to incorporate any other bashisms, then probably just use the tool you have
It is not necessary anymore, but I confirm that I did not know of the existence of the fold command. -sw40 is all I need.
However, as in this way fold just replaces my own compiled utility, the “courageous shell exercise” taught me something new and was necessary.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.