14

for example qa_sharutils-2009-04-22-15-20-39, want chop last 20 bytes, and get 'qa_sharutils'.

I know how to do it in sed, but why $A=${A/.\{20\}$/} does not work?

Thanks!

fedorqui
  • 275,237
  • 103
  • 548
  • 598
jaimechen
  • 511
  • 1
  • 5
  • 17

6 Answers6

43

If your string is stored in a variable called $str, then this will get you give you the substring without the last 20 digits in bash

${str:0:${#str} - 20}

basically, string slicing can be done using

${[variableName]:[startIndex]:[length]}

and the length of a string is

${#[variableName]}

EDIT: solution using sed that works on files:

sed 's/.\{20\}$//' < inputFile
Charles Ma
  • 47,141
  • 22
  • 87
  • 101
  • as a heads up, the `sed` solution will chop of on a per line bases so that `sed 's/.\{2\}$//' <( printf "1st line\n2nd line\n" )` will yield `1st li` and `2nd li`. Hence the strip to chop needs not to contain `` characters. – humanityANDpeace Sep 06 '18 at 13:32
  • `sed '$s/.\{2\}$//'` will work for strings wich contain `` characters – humanityANDpeace Sep 06 '18 at 13:34
  • This didn't work for me in Mac, but this was working https://stackoverflow.com/a/27658717/2704032 – Vishrant Mar 16 '21 at 15:42
2

using awk:

echo $str | awk '{print substr($0,1,length($0)-20)}'

or using strings manipulation - echo ${string:position:length}:

echo ${str:0:$((${#str}-20))}
gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104
Gabriel G
  • 21
  • 2
2

similar to substr('abcdefg', 2-1, 3) in php:

echo 'abcdefg'|tail -c +2|head -c 3
diyism
  • 12,477
  • 5
  • 46
  • 46
1

In the ${parameter/pattern/string} syntax in bash, pattern is a path wildcard-style pattern, not a regular expression. In wildcard syntax a dot . is just a literal dot and curly braces are used to match a choice of options (like the pipe | in regular expressions), so that line will simply erase the literal string ".20".

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
1

There are several ways to accomplish the basic task.

$ str="qa_sharutils-2009-04-22-15-20-39"

If you want to strip the last 20 characters. This substring selection is zero based:

$ echo ${str::${#str}-20}
qa_sharutils

The "%" and "%%" to strip from the right hand side of the string. For instance, if you want the basename, minus anything that follows the first "-":

$ echo ${str%%-*}
qa_sharutils
Stan Graves
  • 6,795
  • 2
  • 18
  • 14
0

only if your last 20 bytes is always date.

$ str="qa_sharutils-2009-04-22-15-20-39"
$ IFS="-"
$ set -- $str
$ echo $1
qa_sharutils
$ unset IFS

or when first dash and beyond are not needed.

$ echo ${str%%-*}
qa_sharutils
ghostdog74
  • 327,991
  • 56
  • 259
  • 343