9

How can I pipe a string and drop a few characters off it?, e.g:

$ echo forbes | ... -3
for
$ echo cucumber | ... -4
cucu
$ echo 1461624333 | .. -3 
1461624
...
etc.

I couldn't find way to use ${str:0:-3} syntax in a pipe.

mklement0
  • 382,024
  • 64
  • 607
  • 775
iLemming
  • 34,477
  • 60
  • 195
  • 309

4 Answers4

19

Piping to sed:

$ echo forbes | sed 's/...$//'
for

This matches the last three characters of the string and removes them (substitutes with the empty string).

To parametrize the number of characters to remove, we can wrap this in a little function:

pipesubstr () {
    sed "s/.\{$1\}$//"
}

to be used as follows:

$ echo forbes | pipesubstr 3
for
$ echo cucumber | pipesubstr 4
cucu
$ echo 1461624333 | pipesubstr 3
1461624
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
9

GNU head is another option (remove the last n characters from the input string as a whole - even if it spans multiple lines):

$ printf '1461624333' | head -c -3   # drop last 3 chars.
1461624

Note that if you use echo instead of printf, there's a trailing \n that must be taken into account, so you must add 1 to the count (and the output won't have a trailing \n).

Caveat: head -c operates on bytes, and therefore only works with single-byte encodings, such as ASCII and extended-ASCII variants (e.g., ISO-8859=1), and therefore not with UTF-8.

mklement0
  • 382,024
  • 64
  • 607
  • 775
8

Use cut?

$ echo "forbes" | cut -b 1-3
for

Update:

To shave from behind, you can do:

echo "forbes" | rev | cut -c (n+1)- | rev

where n is number of characters you want to shave from end

echo "forbes" | rev | cut -c 4- | rev
for
jaypal singh
  • 74,723
  • 23
  • 102
  • 147
1

An awk solution (removes the last n characters from every line in the input):

$ echo '1461624333' | awk -v n=3 '{ print substr($0, 1, length($0)-n) }' # drop last 3 
1461624

Caveat: Not all awk implementations are locale-aware; for instance, BSD awk as found on OS X 10.11.4 is not:

$ echo 'usä' | awk -v n=1 '{ print substr($0, 1, length($0)-n) }'
us? # !! on OSX, mistakenly returns the first byte of multi-byte UTF8 char. 'ä'
mklement0
  • 382,024
  • 64
  • 607
  • 775