54

I want to remove last character from a line:

[root@ozzesh ~]#df -h | awk  '{ print $5 }'
Use%
22%
1%
1%
59%
51%
63%
5%

Expected result:

Use
22
1
1
59
51
63
5
  • 2
    Is it always a % sign? – Bernhard Jul 15 '13 at 5:55

10 Answers 10

84
sed 's/.$//'

To remove the last character.

But in this specific case, you could also do:

df -P | awk 'NR > 1 {print $5+0}'

With the arithmetic expression ($5+0) we force awk to interpret the 5th field as a number, and anything after the number will be ignored.

Note that GNU df (your -h is already a GNU extension, though not needed here) can also be told to only output the disk usage percentage:

df --output=pcent | tail -n +2 | tr -cd '0-9\n'

(tail skips the headers and tr removes everything but the digits and the line delimiters).

On Linux, see also:

findmnt -no USE%
20

With sed, this is pretty easy:

$ cat file
Use%
22%
1%
1%
59%
51%
63%
5%
$ sed 's/.$//' file
Use
22
1
1
59
51
63
5

The syntax is s(ubstitute)/search/replacestring/. The . indicates any character, and the $ the end of the line. So .$ will remove the last character only.

In this case, your complete command would look:

df -h | awk '{ print $5}' | sed 's/.$//'
  • 2
    The pipe to sed is redundant: it can be done in awk: df -h | awk '{gsub(/%/,""); print $5}' – jasonwryan Jul 15 '13 at 6:33
  • @jasonwryan Then I like Stephane's solution better. – Bernhard Jul 15 '13 at 6:35
15

I have two solutions :

  1. cut: echo "somestring1" | rev | cut -c 2- | rev

    Here you reverse the string and cut the string from 2nd character and reverse again.

  2. sed : echo "somestring1" | sed 's/.$//'

    Here you will search for regular expression .$ which means any characters followed by a last character and replace it with null // (between the two slashes)

7

In awk, you could do one of

awk '{sub(/%$/,"",$5); print $5}'
awk '{print substr($5, 1, length($5)-1)}'
2

another approach:

mapfile -t list < <(df -h)
printf '%s\n' "${list[@]%?}"

Turn it into a function:

remove_last() {
  local char=${1:-?}; shift
  mapfile -t list < <("$@")
  printf '%s\n' "${list[@]%$char}"
}

Then call it like this:

remove_last '%' df -h

mapfile is a bash4 feature.

The catch here is that you must supply a character to remove; if you want it to just be whatever the last character happens to be then you must pass '?' or ''. quotes required.

1
$ df -h | awk '{print $5}' | cut -d '%' -f1 
1

Try with this:

df -h | awk  '{ print $5 }' | sed "s/%//"

The normal use is: (ie)

VALUE=987654321
echo X123456789X | sed "s/123456789/${VALUE}/"

Response should be: X987654321X

1
df -h | awk 'NR > 1{ print $5 }' | cut -d "%" -f1
  • This answer could be more helpful to others beyond OP if you could provide a bit of explanation regarding how it works and possibly why this might be better than the alternatives – Fox Apr 1 '17 at 20:09
  • Welcome to Unix Stackexchange! You can take the tour to get a feel for how this site works. When giving an answer it is preferable to give some explanation as to WHY your answer is the one the reader wants. This means it is best if you give some explanation of how it works. If you look above, you will see that all of the highly voted answers explain the code. – Stephen Rauch Apr 1 '17 at 20:10
  • Upvoted for the use of cut -d '%' -f1 which is the correct answer to get everything in the line up to the first '%'. – Titou Dec 10 '18 at 10:36
  • Plus I believe only harmful / wrong answers should ever get downvoted below 0. – Titou Dec 10 '18 at 10:38
0
sed -ie '$d' filename

here -i is to write changes
      e means expression
      $ means last line
      d means delete

Note:Without -e option $ wont work

Optional: To delete 1st and last line use sed -ie '1d;$d' filename

0
echo "123" | perl -ple 'chop'
12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.