bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#19240: cut 8.22 adds newline


From: Eric Blake
Subject: bug#19240: cut 8.22 adds newline
Date: Thu, 04 Dec 2014 14:36:40 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0

On 12/04/2014 11:41 AM, John Kendall wrote:

> 
> The construct in question if just for formatting the output 
> of a script that compares disc files to what's in a database.  
> 
>  echo "$FILE ===========================\c"| cut -c1-30
>  echo " matches =========="

echo '\c' is non-portable.  POSIX says that echo cannot portably used on
any string that uses a backslash (some implementations, like Solaris,
interpret that backslash; others print it literally).  Use 'printf'
instead (in particular, 'printf "%b" "...\c"' does the same as your use
of 'echo "...\c"'; that is, 'printf %b' should be a drop-in replacement
for echoes that know backslash escapes.  On the other hand, if all you
are using is \c to end a line, that's the same as 'printf %s ...' with
no \c)

Also, your example doesn't work for 1-byte $FILE (you don't have enough
=== in the line, and need at least 1 more, which I stick in my responses
below).

Now, for your particular use case:

You can use command substitution to strip trailing newlines, although
that is not portable to builds of cut that skip output if the last line
doesn't have a newline to begin with:

echo "$(printf %b "$FILE ============================\c"| cut -c1-30)" \
     " matches =========="

but you can guarantee a newline ending, and get rid of the non-portable
\ to echo, all for a shorter line that portably works:

echo "$(echo "$FILE ============================"| cut -c1-30)" \
     " matches =========="

'head' can do what you are using cut for:

 echo "$FILE ============================" | head -c30
 echo " matches =========="

And if you are using bash, you can even do it without forking:

 line="$FILE ============================"
 line=${line::30}
 echo "$line matches =========="

There's probably lots of other one-liner solutions that don't require
particular behavior of 'cut'.


> This can be re-written, of course.  (There is one corner case that 
> Solaris's cut handled nicely that I have not been able to come up 
> with a quick fix.) 

Hope my quick fix ideas help you.  Feel free to keep asking questions,
although you are now moving the topic a bit more into the realm of shell
programming than coreutils usage.  And remember, it always helps to ask
questions related to your end goal, rather than your attempted solution:

https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem
http://www.perlmonks.org/?node=XY+Problem

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]