13

How can I remove the last n characters from a particular string using shell script?

This is my input:

ssl01:49188,,,
ssl01:49188,
ssl01:49188,,,,,
ssl01:49188,ssl999999:49188,,,,,
ssl01:49188,abcf999:49188,,,,,

The output should be in the following format:

ssl01:49188
ssl01:49188
ssl01:49188
ssl01:49188,ssl999999:49188
ssl01:49188,abcf999:49188
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
anish
  • 6,884
  • 13
  • 74
  • 140

4 Answers4

42

To answer the title of you question with specifies cutting last n character in a string, you can use the substring extraction feature in Bash.

me@home$ A="123456"
me@home$ echo ${A:0:-2}  # remove last 2 chars
1234

However, based on your examples you appear to want to remove all trailing commas, in which case you could use sed 's/,*$//'.

me@home$ echo "ssl01:49188,ssl999999:49188,,,,," | sed 's/,*$//'
ssl01:49188,ssl999999:49188

or, for a purely Bash solution, you could use substring removal:

me@home$ X="ssl01:49188,ssl999999:49188,,,,,"
me@home$ shopt -s extglob
me@home$ echo ${X%%+(,)}
ssl01:49188,ssl999999:49188

I would use the sed approach if the transformation needs to be applied to a whole file, and the bash substring removal approach if the target string is already in a bash variable.

Shawn Chin
  • 84,080
  • 19
  • 162
  • 191
  • 6
    Please note that the first solution only works for newer versions of Bash (>= 4.2-alpha). – chiborg Jun 19 '13 at 13:41
  • 11
    for older versions: use #item to get length of the string, so if you are trying to remove last n chars, do it like item="abcdefgh" echo ${item:0:${#item}-n}; – rivu Nov 13 '13 at 18:17
  • I know this is trivial, but figured I would state it here because it tripped me up. Make sure you put the semi-colon on the end just like rivu has it! I forgot the semi-colon and got all sorts of errors! – user972276 Jan 27 '14 at 17:18
  • @user972276: There is no need for a semicolon at the _end_, but you do need semicolons to _separate_ multiple commands on a single line. rivu's full Bash 3.x example on a single line is therefore: `n=2; item='abcdefgh'; echo "${item:0:${#item}-n}"` – mklement0 Apr 26 '16 at 01:59
12

With sed:

sed 's/,\+$//' file
cmbuckley
  • 40,217
  • 9
  • 77
  • 91
  • 1
    That works well, but only with _GNU_ `sed`. A POSIX-compliant reformulation is `sed 's/,\{1,\}//'`. A version that works with both GNU and BSD/OSX `sed`: `sed -E 's/,+//'` – mklement0 Apr 26 '16 at 02:02
1

I guess you need to remove those unnecessary ,'s

sed 's/,,//g;s/\,$//g' your_file

tested:

> cat temp
ssl01:49188,,,
ssl01:49188,
ssl01:49188,,,,,
ssl01:49188,,,
ssl01:49188,
ssl01:49188,,,,,
ssl01:49188,ssl999999:49188,,,,,
ssl01:49188,abcf999:49188,,,,,
> sed 's/,,//g;s/\,$//g' temp
ssl01:49188
ssl01:49188
ssl01:49188
ssl01:49188
ssl01:49188
ssl01:49188
ssl01:49188,ssl999999:49188
ssl01:49188,abcf999:49188
> 
Vijay
  • 65,327
  • 90
  • 227
  • 319
1

Using sed:

sed 's/,,*$//g' file 
Guru
  • 16,456
  • 2
  • 33
  • 46