Extract digits using sed with /s - sed

I want to extract the value with op/s
pgmap 512 pgs: 512 active+clean; 1.39TiB data, 4.08TiB used, 1.15TiB / 5.24TiB avail; 4.43MiB/s wr, 46op/s
pginfo="pgmap 512 pgs: 512 active+clean; 1.39TiB data, 4.08TiB used, 1.15TiB / 5.24TiB avail; 4.43MiB/s wr, 46op/s"
echo $pginfo | sed -n '/pgmap/s/.* \([0-9]*\) op\/s.*/\1/p'
But it does not return anything. Any help pointers will be appreciated.

Your regex is looking for a space after the digits but there isn't one.
Also you should quote the echoed variable to prevent it being mangled.
echo "$pginfo" | sed -n '/pgmap/s/.* \([0-9][0-9]*\)op\/s.*/\1/p'

Related

Remove useless .0 from txt files in bash

How can I remove useless ".0" strings in a txt file of numbers?
If I have this file:
43.65 24.0 889.5 5.0
32.14 32.0 900.0 6.0
38.27 43.0 899.4 5.0
I want to get:
43.65 24 889.5 5
32.14 32 900 6
38.27 43 899.4 5
I tried: sed 's|\.0 | |g' but that obviously does not work with new lines and EOF.
Any suggestion without getting into python, etc?
This might work for you (GNU sed):
sed 's/\.0\b//g' file
Or
sed 's/\.0\>//g' file
Remove any period followed by a zero followed by a word boundary.
You can use
sed -E 's,([0-9])\.0($| ),\1\2,g' file
Details:
-E - enables POSIX ERE syntax
([0-9])\.0($| ) - finds and captures into Group 1 a digit, then matches .0, and then matches and captures into Group 2 a space or end of string
\1\2 - replaces with Group 1 + Group 2 concatenated values
g - replaces all occurrences.
See the online demo:
s='43.65 24.0 889.5 5.0
32.14 32.0 900.0 6.0
38.27 43.0 899.4 5.0'
sed -E 's,([0-9])\.0($| ),\1\2,g' <<< "$s"
Output:
43.65 24 889.5 5
32.14 32 900 6
38.27 43 899.4 5

How to extract data set from a text file?

Am quite new in the Unix field and I am currently trying to extract data set from a text file. I tried with sed, grep, awk but it seems to only work with extracting lines, but I want to extract an entire dataset... Here is an example of file from which I'd like to extract the 2 data sets (figures after the lines "R.Time Intensity")
[Header]
Application Name LabSolutions
Version 5.87
Data File Name C:\LabSolutions\Data\Antoine\170921_AC_FluoSpectra\069_WT3a derivatized lignin LiCl 430_GPC_FOREVER_430_049.lcd
Output Date 2017-10-12
Output Time 12:07:32
[Configuration]
Instrument Name BOTAN127-Instrument1
Instrument # 1
Line # 1
# of Detectors 3
Detector ID Detector A Detector B PDA
Detector Name Detector A Detector B PDA
# of Channels 1 1 2
[LC Chromatogram(Detector A-Ch1)]
Interval(msec) 500
# of Points 9603
Start Time(min) 0,000
End Time(min) 80,017
Intensity Units mV
Intensity Multiplier 0,001
Ex. Wavelength(nm) 405
Em. Wavelength(nm) 430
R.Time (min) Intensity
0,00000 -709779
0,00833 -709779
0,01667 17
0,02500 3
0,03333 7
0,04167 19
0,05000 9
0,05833 5
0,06667 2
0,07500 24
0,08333 48
[LC Chromatogram(Detector B-Ch1)]
Interval(msec) 500
# of Points 9603
Start Time(min) 0,000
End Time(min) 80,017
Intensity Units mV
Intensity Multiplier 0,001
R.Time (min) Intensity
0,00000 149
0,00833 149
0,01667 -1
I would greatly appreciate any idea. Thanks in advance.
Antoine
awk '/^[^0-9]/&&d{d=0} /R.Time/{d=1}d' file
Brief explanation,
Set d as a flag to determine print line or not
/^[^0-9]/&&d{d=0}: if regex ^[^0-9] matched && d==1, disabled d
/R.Time/{d=1}: if string "R.Time" searched, enabled d
awk '/R.Time/,/LC/' file|grep -v -E "R.Time|LC"
grep part will remove the R.Time and LC lines that come as a part of the output from awk
I think it's a job for sed.
sed '/R.Time/!d;:A;N;/\n$/!bA' infile

Change an exact word on exact roll in ASCII file

I need to change a string from a file, which repeats on every row, but I need to change it only for couple of rows (not for all rows).
Lets say, the /etc/fstab file:
/dev/mapper/rhel-root / xfs defaults 0 0
/dev/mapper/rhel-boot /boot ext4 defaults 1 2
/dev/mapper/rhel-home /home ext3 defaults 1 2
/dev/mapper/rhel-var /var ext3 defaults 1 2
/dev/mapper/workvg-swaplv swap swap defaults 0 0
How can I change the "defaults" string to "string" only for /home and /var entries?
the thinks I've tried are using a lot of combinations of grep|sed|exargs etc., but it doesn't work as expected :)
echo $(egrep "/var | /home" fstab | awk '{ print $4}') | xargs -I '{}' sed 's/{}/string/' fstab
Can someone gives me some idea regarding this?
Thank you in advance guys!
$ sed -E '/\/(home|var)/ s/defaults/string/' fstab
/dev/mapper/rhel-root / xfs defaults 0 0
/dev/mapper/rhel-boot /boot ext4 defaults 1 2
/dev/mapper/rhel-home /home ext3 string 1 2
/dev/mapper/rhel-var /var ext3 string 1 2
/dev/mapper/workvg-swaplv swap swap defaults 0 0
-E use extended regex
/\/(home|var)/ this is to match only those lines with /home or /var
s/defaults/string/ substitute required pattern with replacement string
Edit:
For more robust matching:
sed -E '/^\S+\s+\/(home|var)\b/ s/^((\S+\s+){3})defaults\b/\1string/' fstab
This checks for exact match of /home or /var in 2nd column and replaces exact match of defaults in 4th column
\b checks for word boundary, \s matches whitespace, \S matches other than whitespace
This will work robustly for all input lines and for all values of defaults and string that do not contain backslashes (an easy tweak if you do have those):
$ cat tst.awk
BEGIN { split(entries,t); for (i in t) tgts["/"t[i]] }
($2 in tgts) && match($0,/^((\S+\s+){3})(\S+)(\s.*)$/,a) && (a[3]==old) { $0 = a[1] new a[4] }
{ print }
$ awk -v entries="home var" -v old="defaults" -v new="string" -f tst.awk file
/dev/mapper/rhel-root / xfs defaults 0 0
/dev/mapper/rhel-boot /boot ext4 defaults 1 2
/dev/mapper/rhel-home /home ext3 string 1 2
/dev/mapper/rhel-var /var ext3 string 1 2
/dev/mapper/workvg-swaplv swap swap defaults 0 0
It uses GNU awk for the 3rd arg to match(), other awks would use substr().
$ awk '/\/var/ || /\/home {sub(/defaults/, "string")} 1'` /etc/fstab
/\/var || /\/home if keywords in the record
sub{/defaults/, "string") replace first "defaults" with "string"
1 print changed and unchanged records
awk '/home|var/{sub(/defaults/,"string ")}1' file
/dev/mapper/rhel-root / xfs defaults 0 0
/dev/mapper/rhel-boot /boot ext4 defaults 1 2
/dev/mapper/rhel-home /home ext3 string 1 2
/dev/mapper/rhel-var /var ext3 string 1 2
/dev/mapper/workvg-swaplv swap swap defaults 0 0

AWK - filter file with not equal fields

I've been trying to pull a field from a row in a file although each row may have plus or minus 2 or 3 fields per row. They aren't always equal in the number of fields per row.
Here is a snippet:
A orarpp 45286124 1 1 0 20 60 Nov 25 9-16:42:32 01:04:58 11176 117056 0 - oracleXXX (LOCAL=NO)
A orarpp 45351560 1 1 3 20 61 Nov 30 5-03:54:42 02:24:48 4804 110684 0 - ora_w002_XXX
A orarpp 45548236 1 1 22 20 71 Nov 26 8-19:36:28 00:56:18 10628 116508 0 - oracleXXX (LOCAL=NO)
A orarpp 45679190 1 1 0 20 60 Nov 28 6-23:42:20 00:37:59 10232 116112 0 - oracleXXX (LOCAL=NO)
A orarpp 45744808 1 1 0 20 60 10:52:19 23:08:12 00:04:58 11740 117620 0 - oracleXXX (LOCAL=NO)
A root 45810380 1 1 0 -- 39 Nov 25 9-19:54:34 00:00:00 448 448 0 - garbage
In the case of the first line, I'm interested in 9-16:42:32 and the similar fields for each row.
I've tried to pull it by using ':' as the field separator and then filter from there however, what I am trying to accomplish is to do something if the number before the dash (in the example it's 9) is greater than one.
cat file.txt | grep oracle | awk -F: '{print substr($1, length($1)-5)}'
This is because the number of fields on either side of the actual field I need can be different from line to line.
Definitely not the most efficient but I've been trying to do this with an awk one liner.
Hints or a direction would be appreciated to get me moving again. I am not opposed to doing in a better way than awk.
Thanks.
Maybe cut is the right tool for this job? For example, with your snippet:
$ cut -c 62-71 file.txt
9-16:42:32
5-03:54:42
8-19:36:28
6-23:42:20
23:08:12
9-19:54:34
The arguments tell cut to snip columns (-c) 62 through 71.
For additional processing, you can pipe it to awk.
You can also accomplish the whole thing in awk by accepting entire lines and then using substr to extract the columns you want. For example, this awk command produces the same output as the cut command above:
awk '{ print substr($0, 62, 10) }' file.txt
Whether you create a pipeline or do the processing entirely in awk is at least in part a matter of personal taste / style.
Would this do?
awk -F: '/oracle/ {print substr($0,62,10)}' file.txt
9-16:42:32
8-19:36:28
6-23:42:20
23:08:12
This search for oracle and then print 10 characters starting from position 62
You can grab those identifiers with one of
grep -o '[[:digit:]]\+-[[:digit:]]\{2\}:[[:digit:]]\{2\}:[[:digit:]]\{2\}'
grep -oP '\d+-\d\d:\d\d:\d\d' # GNU grep
It sounds like you want to do something with the lines, not just find the ids. Please elaborate.
Using GNU awk:
gawk --re-interval '
/oracle/ && \
match($0, /([[:digit:]]+)-([[:digit:]]{2}:){2}[[:digit:]]{2}/, a) && \
a[1]>1 {
# do something with the matching line
print
}
' file

sed for checking hex syntax

I have follow file:
cat 123
# carriers mask for G1,G2 (96 - 168 kHz)
# 91, 4, {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF} \
# carriers mask for G3 (96 - 288 kHz)
# 91, 4, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF} \
and want to check if have correct string in figural parentheses
I wrote following expression (check if every from 12 hex expression has correct syntax)
sed -r -n '/^.*91, 4, {\(0x[0-9A-F],\)\{11\}0x[0-9A-F]}.*/p' 123
sed: bad regex '^.*91, 4, {\(0x[0-9A-F],\)\{11\}0x[0-9A-F]}.*': Invalid content of \{\}
I tried to make expression in other way
sed -rne '/^.*91, 4, {0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F]}.*/ {p}' 123
sed: bad regex '^.*91, 4, {0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F],0x[0-9A-F]}.*': Invalid content of \{\}
Can anybody indicate where is my mistake?
Thank you in advance.
There should be no -r option and you were only checking for single digits. You could try something like:
sed -n '/91, 4, {\(0x[0-9A-F][0-9A-F],\)\{11\}0x[0-9A-F][0-9A-F]}/p' file