Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 May 2013 16:27:53 +0000
From:      "Teske, Devin" <Devin.Teske@fisglobal.com>
To:        Devin Teske <dteske@freebsd.org>
Cc:        Tim Daneliuk <tundra@tundraware.com>, FreeBSD Questions <freebsd-questions@freebsd.org>
Subject:   Re: check variable content size in sh script
Message-ID:  <13CA24D6AB415D428143D44749F57D7201F4D4C9@ltcfiswmsgmb26>
In-Reply-To: <13CA24D6AB415D428143D44749F57D7201F4D41F@ltcfiswmsgmb26>
References:  <5194F65F.6080503@a1poweruser.com> <5194FB0A.9090400@tundraware.com> <13CA24D6AB415D428143D44749F57D7201F4D41F@ltcfiswmsgmb26>

next in thread | previous in thread | raw e-mail | index | archive | help

On May 16, 2013, at 9:06 AM, Teske, Devin wrote:

>=20
> On May 16, 2013, at 8:28 AM, Tim Daneliuk wrote:
>=20
>> On 05/16/2013 10:08 AM, Joe wrote:
>>> Hello
>>>=20
>>> Have script that has max size on content in a variable.
>>> How to code size less than 51 characters?
>>>=20
>>=20
>> FOO=3D"Some string you want to check length of"
>> FOOLEN=3D`echo $FOO | wc | awk '{print $3}'`
>>=20
>=20
> Uh, without forking to 2 separate programs=85
>=20
> FOOLEN=3D${#FOO}
>=20
>=20
>> You can then use $FOOLEN in a conditional.
>>=20
>=20
>=20
> However, if the OP wanted to actually truncate $FOO to 51 characters:
>=20
>=20
> NEWFOO=3D$( echo "$FOO" | awk -v max=3D51 '{print substr($0,0,max)}' )
>=20
>=20
> However, if you want to handle the case of $FOO containing newlines (and =
you want the newline to count toward the max), then this instead would do t=
he trick:
>=20
>=20
> NEWFOO=3D$( echo "$FOO" | awk -v max=3D51 '
> 	{
> 		len =3D length($0)
> 		max -=3D len
> 		print substr($0,0,(max > 0 ? len : max + len))
> 		if ( max < 0 ) exit
> 		max--
> 	}' )
>=20

For fun, I decided to expand on the solution I provided immediately above=
=85 turning it into a function that you might be a little more familiar wit=
h:

snprintf()
{
        local __var_to_set=3D"$1" __size=3D"$2"
        shift 2 # var_to_set/size
        eval "$__var_to_set"=3D\$\( printf \"\$@\" \| awk -v max=3D\"\$__si=
ze\" \''
        {
                len =3D length($0)
                max -=3D len
                print substr($0,0,(max > 0 ? len : max + len))
                if ( max < 0 ) exit
                max--
        }'\' \)
}

Example usage:

FOO=3D$( printf "abc\n123\n" )
snprintf NEWFOO 6 "%s" "$FOO"
echo "NEWFOO=3D[$NEWFOO] len=3D[${#NEWFOO}]"

Produces:

NEWFOO=3D[abc
12] len=3D[6]

Hopefully this should help some folks.
--=20
Devin



>=20
> $NEWFOO, even if multi-line, will be limited to 51-bytes (adjust max=3D51=
 accordingly for other desired-lengths). Newlines are preserved.
>=20
> Last, but not least, if you want to be able to handle multi-line values b=
ut only want to return the first line up-to N bytes (using 51 as the OP use=
d):
>=20
>=20
> NEWFOO=3D$( echo "$FOO" | awk -v max=3D51 '{ print substr($0,0,max); exit=
 }' )
>=20
>=20
> If $FOO had multiple lines, $NEWFOO will have only the first line (and it=
 will be truncated to 51 bytes or less).
> --=20
> Devin

_____________
The information contained in this message is proprietary and/or confidentia=
l. If you are not the intended recipient, please: (i) delete the message an=
d all copies; (ii) do not disclose, distribute or use the message in any ma=
nner; and (iii) notify the sender immediately. In addition, please be aware=
 that any message addressed to our domain is subject to archiving and revie=
w by persons other than the intended recipient. Thank you.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?13CA24D6AB415D428143D44749F57D7201F4D4C9>