LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 01-07-2020, 04:50 AM   #1
undefineduser
LQ Newbie
 
Registered: Nov 2019
Distribution: Arch
Posts: 9

Rep: Reputation: Disabled
sed - Replace numbers from one to several digits


Hello,

I am currently learning how to use sed and want to format a sample output of smartctl.

This is the output:
Code:
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000f   099   099   051    Pre-fail  Always       -       2376
  3 Spin_Up_Time            0x0007   091   091   011    Pre-fail  Always       -       3620
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       405
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x000f   253   253   051    Pre-fail  Always       -       0
  8 Seek_Time_Performance   0x0025   100   100   015    Pre-fail  Offline      -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       717
 10 Spin_Retry_Count        0x0033   100   100   051    Pre-fail  Always       -       0
 11 Calibration_Retry_Count 0x0012   100   100   000    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       405
 13 Read_Soft_Error_Rate    0x000e   099   099   000    Old_age   Always       -       2375
183 Runtime_Bad_Block       0x0032   100   100   000    Old_age   Always       -       0
184 End-to-End_Error        0x0033   100   100   000    Pre-fail  Always       -       0
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       2375
188 Command_Timeout         0x0032   100   100   000    Old_age   Always       -       0
190 Airflow_Temperature_Cel 0x0022   084   074   000    Old_age   Always       -       16 (Lifetime Min/Max 16/16)
194 Temperature_Celsius     0x0022   084   071   000    Old_age   Always       -       16 (Lifetime Min/Max 16/16)
195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age   Always       -       3558
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0012   098   098   000    Old_age   Always       -       81
198 Offline_Uncorrectable   0x0030   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x003e   100   100   000    Old_age   Always       -       1
200 Multi_Zone_Error_Rate   0x000a   100   100   000    Old_age   Always       -       0
201 Soft_Read_Error_Rate    0x000a   253   253   000    Old_age   Always       -       0
My goal is to remove the ID numbers (so 1 - 201).
At the moment my command removes just the first digit of every number:

Code:
root@localhost:/var/prtg/scriptsxml# smartctl | grep -A25 'Vendor' | sed -n -E 's/(\s*)[0-9](\s*)//p'
Raw_Read_Error_Rate     0x000f   099   099   051    Pre-fail  Always       -       2376
Spin_Up_Time            0x0007   091   091   011    Pre-fail  Always       -       3620
Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       405
Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
Seek_Error_Rate         0x000f   253   253   051    Pre-fail  Always       -       0
Seek_Time_Performance   0x0025   100   100   015    Pre-fail  Offline      -       0
Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       717
0 Spin_Retry_Count        0x0033   100   100   051    Pre-fail  Always       -       0
1 Calibration_Retry_Count 0x0012   100   100   000    Old_age   Always       -       0
2 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       405
3 Read_Soft_Error_Rate    0x000e   099   099   000    Old_age   Always       -       2375
83 Runtime_Bad_Block       0x0032   100   100   000    Old_age   Always       -       0
84 End-to-End_Error        0x0033   100   100   000    Pre-fail  Always       -       0
87 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       2375
88 Command_Timeout         0x0032   100   100   000    Old_age   Always       -       0
90 Airflow_Temperature_Cel 0x0022   084   074   000    Old_age   Always       -       16 (Lifetime Min/Max 16/16)
94 Temperature_Celsius     0x0022   084   071   000    Old_age   Always       -       16 (Lifetime Min/Max 16/16)
95 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age   Always       -       3558
96 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
97 Current_Pending_Sector  0x0012   098   098   000    Old_age   Always       -       81
98 Offline_Uncorrectable   0x0030   100   100   000    Old_age   Offline      -       0
99 UDMA_CRC_Error_Count    0x003e   100   100   000    Old_age   Always       -       1
00 Multi_Zone_Error_Rate   0x000a   100   100   000    Old_age   Always       -       0
01 Soft_Read_Error_Rate    0x000a   253   253   000    Old_age   Always       -       0
How do I rewrite the command to remove two- and three-digit numbers?

Last edited by undefineduser; 01-07-2020 at 04:52 AM.
 
Old 01-07-2020, 04:59 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,932

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
there are several ways to do that:
Code:
sed 's/^....//'       # remove the first 4 chars
sed 's/^\s*[0-9]* //' # remove space, digits and a space
sed -r 's/^\s*[0-9]+\s//'   # probably this works too
 
Old 01-07-2020, 05:05 AM   #3
Turbocapitalist
LQ Guru
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 7,332
Blog Entries: 3

Rep: Reputation: 3727Reputation: 3727Reputation: 3727Reputation: 3727Reputation: 3727Reputation: 3727Reputation: 3727Reputation: 3727Reputation: 3727Reputation: 3727Reputation: 3727
Well, first if you want to skip the first line of the output,

Code:
sed -n -E '1d; s/(\s*)[0-9]//p'
But that still leaves you with your original problem. The sed language can't really do comparisons or calculations, so I would suggest AWK instead.

Code:
smartctl | awk '$1+0<100'
Back to the original question, if you are not looking for a criterion more specific than the number of digits in the first column, then use interval operators,

Code:
smartctl | sed -n -E '/^[[:space:]]*[0-9]{1,2}[[:space:]]/p'

# or 

smartctl | sed -n -E '/^[[:space:]]*[0-9]{1,2}\b/p'
 
Old 01-07-2020, 07:06 AM   #4
individual
Member
 
Registered: Jul 2018
Posts: 315
Blog Entries: 1

Rep: Reputation: 233Reputation: 233Reputation: 233
My solution is not too different from what the others have posted, except I combined the characters into a character class.
Code:
sed 's/^[[:space:][:digit:]]+//g'
To match and remove one or more whitespace/numeric characters from the beginning of each line.
 
Old 01-07-2020, 11:03 AM   #5
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,803

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Quote:
Originally Posted by individual View Post
My solution is not too different from what the others have posted, except I combined the characters into a character class.
Code:
sed 's/^[[:space:][:digit:]]+//g'
To match and remove one or more whitespace/numeric characters from the beginning of each line.
Since your pattern specifies the beginning of the line, isn't the trailing "g" superfluous?
 
Old 01-07-2020, 12:02 PM   #6
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,616

Rep: Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554Reputation: 2554
To replace from one to several digits, use the + quantifier (or its lazy variant +?) combined with [0-9] (because sed doesn't support \d and [[:digit:]] is unnecessarily verbose).

+ means "as many as possible, at least one"
+? means "at least one, as many as required"

Contrasted with * which means "as many as possible, none required", and *? which means "as few as possible".

The difference between greedy and lazy quantifiers can be subtle - in your example it doesn't matter which is used, but there are other situations where it does matter, so it's a useful thing to keep in mind.

Note that sed needs extended mode (-E) for all the above to work except *

So, to handle lines starting with optional spaces, then at least one digit, then a space:
Code:
sed -E 's/^ *[0-9]+ //'
One final note, the above uses literal space characters. Both \s and the long-winded [[:space:]] match five additional whitespace characters other than space, so for clarity should be avoided when only looking for spaces.

Last edited by boughtonp; 01-07-2020 at 12:03 PM.
 
Old 01-07-2020, 04:22 PM   #7
individual
Member
 
Registered: Jul 2018
Posts: 315
Blog Entries: 1

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by rnturn View Post
Since your pattern specifies the beginning of the line, isn't the trailing "g" superfluous?
Indeed, good catch. I do it out of habit.
 
  


Reply

Tags
bash, linux, sed



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Replace numbers with another numbers using sed in multiple files Asoo Linux - Newbie 2 05-31-2017 03:57 AM
[SOLVED] Does groove IP has a bug when entering account numbers or long digits Geek255 Linux - Mobile 1 03-09-2012 08:01 PM
Zenwalk 6.4 arabic digits/numbers not working hottdogg Zenwalk 0 01-17-2011 03:32 AM
Find several different words and replace with one using sed. Techno Guy Linux - Newbie 18 07-06-2009 07:16 AM
BASH - convert single digits to double digits. rickenbacherus Programming 7 05-07-2008 06:53 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 01:18 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration