Bash: how to delete the last character

I am trying to extract some information from the output of a bash command:

uptime | awk '{print $3}' 

When I start, I get this result: 8:27,

How to remove the last character (i.e. comma)?

+4
source share
5 answers

Another option (replacing awk and sed with cut ):

 # "unnecessary" echo with evil backticks to get rid of extra spaces echo `uptime|cut -d, -f1' 

seems to work ... until the uptime reaches one day (thanks to @sudo_O for the tip). Then the output format will contain the number of days, and we will need

 echo `uptime|cut -d, -f2` 

(the latter was my initial answer because I tested with uptime> 24 hours).

UPD: both solutions really do not work: the latter prints hours of uptime without any days, the former cannot extract the hours because there are no comma delimiters in front of them when there are no days - but the rest of the answer is actually proved by these failures.

The whole approach is error prone. What happens after several months and years? (It seems that I remember that it still shows N days, but I could be wrong). What if the uptime is always localized? (They refused to do this for the sake of existing scripts?) What does it show for 1 user, "1 user" or "1 user"? If we know all the answers, do we want to depend on them?

If our goal demonstrates uptime for the user, extracting the part between the โ€œupโ€ and the โ€œusersโ€ using a regular expression could do the trick:

 uptime | sed 's/^.*up\(.*\), *[0-9]\+ *users.*$/\1/' 

If we want to compare time or collect statistics, something like the Linux-specific /proc/uptime will work better (the first column in /proc/uptime is the uptime).

+9
source

You almost had it, only substr or gsub functions with awk

 $ uptime | awk '{print substr($3,1,length($3)-1)}' 2:49 $ uptime | awk '{sub(/,/,"");print $3}' 2:49 

There is no need for excess piping or improper use of the back protrusions.

An even more reliable solution is better, given the uptime excellent output using (GNU) grep -Po "\d{1,2}:\d{2}(?=,)" :

 # More than one day $ uptime 12:46:18 up 92 days, 5:00, 2 users, load average: 0.00, 0.01, 0.05 $ uptime | grep -Po "\d{1,2}:\d{2}(?=,)" 5:00 # Less than one day $ uptime 12:47:30 up 4:24, 7 users, load average: 0.34, 0.12, 0.07 $ uptime | grep -Po "\d{1,2}:\d{2}(?=,)" 4:24 

Or using sed -rn 's/.*([0-9]{1,2}:[0-9]{2}),.*/\1/p :

 # More than one day $ uptime 12:54:00 up 92 days, 5:07, 2 users, load average: 0.03, 0.02, 0.05 $ uptime | sed -rn 's/.*([0-9]{1,2}:[0-9]{2}),.*/\1/p' 5:07 # Less than one day $ uptime 12:54:55 up 4:31, 7 users, load average: 0.07, 0.10, 0.08 $ uptime | sed -rn 's/.*([0-9]{1,2}:[0-9]{2}),.*/\1/p' 4:31 

UPDATE: So if uptime less than an hour, if another time !?

 $ uptime 14:46:03 up 3 min, 4 users, load average: 0.54, 0.75, 0.36 $ uptime 14:53:40 up 11 min, 4 users, load average: 0.48, 0.62, 0.46 

One regexp to manage all of them:

 $ sed -rn 's/.*up\s+(.*),\s+[0-9]+ users.*/\1/p' file 92 days, 5:00 4:24 11 min 3 min 

I guess this also applies to years!

+7
source

uptime | awk '{print $3}' | tr -d ,

+4
source

This error handling result @sudo_O (thanks!):

 $ cat file 12:46:18 up 92 days, 5:00, 2 users, load average: 0.00, 0.01, 0.05 12:47:30 up 4:24, 7 users, load average: 0.34, 0.12, 0.07 $ awk -F'[ ,]+' '{print $3 (/days/?" "$4" "$5:"")}' file 92 days 5:00 4:24 $ sed 's/.*up *\(.*\), *[0-9]* users.*/\1/' file 92 days, 5:00 4:24 
+2
source

Use sed :

 uptime | awk '{print $3}' | sed '$ s/,$//' 
+1
source

All Articles