[bash] How to remove the last character from a bash grep output

COMPANY_NAME=`cat file.txt | grep "company_name" | cut -d '=' -f 2` 

outputs something like this

"Abc Inc";

What I want to do is I want to remove the trailing ";" as well. How can i do that? I am a beginner to bash. Any thoughts or suggestions would be helpful.

This question is related to bash grep

The answer is


don't have to chain so many tools. Just one awk command does the job

 COMPANY_NAME=$(awk -F"=" '/company_name/{gsub(/;$/,"",$2) ;print $2}' file.txt)

Some refinements to answer above. To remove more than one char you add multiple question marks. For example, to remove last two chars from variable $SRC_IP_MSG, you can use:

SRC_IP_MSG=${SRC_IP_MSG%??}

Don't abuse cats. Did you know that grep can read files, too?

The canonical approach would be this:

grep "company_name" file.txt | cut -d '=' -f 2 | sed -e 's/;$//'

the smarter approach would use a single perl or awk statement, which can do filter and different transformations at once. For example something like this:

COMPANY_NAME=$( perl -ne '/company_name=(.*);/ && print $1' file.txt )

I am not finding that sed 's/;$//' works. It doesn't trim anything, though I'm wondering whether it's because the character I'm trying to trim off happens to be a "$". What does work for me is sed 's/.\{1\}$//'.


you can strip the beginnings and ends of a string by N characters using this bash construct, as someone said already

$ fred=abcdefg.rpm
$ echo ${fred:1:-4}
bcdefg

HOWEVER, this is not supported in older versions of bash.. as I discovered just now writing a script for a Red hat EL6 install process. This is the sole reason for posting here. A hacky way to achieve this is to use sed with extended regex like this:

$ fred=abcdefg.rpm
$ echo $fred | sed -re 's/^.(.*)....$/\1/g'
bcdefg

In Bash using only one external utility:

IFS='= ' read -r discard COMPANY_NAME <<< $(grep "company_name" file.txt)
COMPANY_NAME=${COMPANY_NAME/%?}

Using sed, if you don't know what the last character actually is:

$ grep company_name file.txt | cut -d '=' -f2 | sed 's/.$//'
"Abc Inc"

cat file.txt | grep "company_name" | cut -d '=' -f 2 | cut -d ';' -f 1

foo="hello world"
echo ${foo%?}
hello worl

This will remove the last character contained in your COMPANY_NAME var regardless if it is or not a semicolon:

echo "$COMPANY_NAME" | rev | cut -c 2- | rev

I'd use head --bytes -1, or head -c-1 for short.

COMPANY_NAME=`cat file.txt | grep "company_name" | cut -d '=' -f 2 | head --bytes -1`

head outputs only the beginning of a stream or file. Typically it counts lines, but it can be made to count characters/bytes instead. head --bytes 10 will output the first ten characters, but head --bytes -10 will output everything except the last ten.

NB: you may have issues if the final character is multi-byte, but a semi-colon isn't

I'd recommend this solution over sed or cut because

  • It's exactly what head was designed to do, thus less command-line options and an easier-to-read command
  • It saves you having to think about regular expressions, which are cool/powerful but often overkill
  • It saves your machine having to think about regular expressions, so will be imperceptibly faster

I believe the cleanest way to strip a single character from a string with bash is:

echo ${COMPANY_NAME:: -1}

but I haven't been able to embed the grep piece within the curly braces, so your particular task becomes a two-liner:

COMPANY_NAME=$(grep "company_name" file.txt); COMPANY_NAME=${COMPANY_NAME:: -1} 

This will strip any character, semicolon or not, but can get rid of the semicolon specifically, too. To remove ALL semicolons, wherever they may fall:

echo ${COMPANY_NAME/;/}

To remove only a semicolon at the end:

echo ${COMPANY_NAME%;}

Or, to remove multiple semicolons from the end:

echo ${COMPANY_NAME%%;}

For great detail and more on this approach, The Linux Documentation Project covers a lot of ground at http://tldp.org/LDP/abs/html/string-manipulation.html


Assuming the quotation marks are actually part of the output, couldn't you just use the -o switch to return everything between the quote marks?

COMPANY_NAME="\"ABC Inc\";" | echo $COMPANY_NAME | grep -o "\"*.*\""