How to remove the last character from a bash grep output

BashGrep

Bash Problem Overview


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.

Bash Solutions


Solution 1 - Bash

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

Solution 2 - Bash

I'd use sed 's/;$//'. eg:

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

Solution 3 - Bash

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

Solution 4 - Bash

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

Solution 5 - Bash

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

Solution 6 - Bash

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"

Solution 7 - Bash

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 )

Solution 8 - Bash

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)

Solution 9 - Bash

In Bash using only one external utility:

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

Solution 10 - Bash

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 "\"*.*\""

Solution 11 - Bash

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%??}

Solution 12 - Bash

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

Solution 13 - Bash

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\}$//'.

Solution 14 - Bash

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionliv2hakView Question on Stackoverflow
Solution 1 - Bashztank1013View Answer on Stackoverflow
Solution 2 - BashLaurence GonsalvesView Answer on Stackoverflow
Solution 3 - BashgroksterView Answer on Stackoverflow
Solution 4 - BashAaron J LangView Answer on Stackoverflow
Solution 5 - BashmightypileView Answer on Stackoverflow
Solution 6 - BashDetView Answer on Stackoverflow
Solution 7 - BashHas QUIT--Anony-MousseView Answer on Stackoverflow
Solution 8 - BashkurumiView Answer on Stackoverflow
Solution 9 - BashDennis WilliamsonView Answer on Stackoverflow
Solution 10 - BashJens BodalView Answer on Stackoverflow
Solution 11 - BashyuliskovView Answer on Stackoverflow
Solution 12 - BashnecromancerView Answer on Stackoverflow
Solution 13 - BashktappeView Answer on Stackoverflow
Solution 14 - BashPaul MView Answer on Stackoverflow