I've got the following:
sed -i "s/SYNFLOOD_RATE = \"100/s\"/SYNFLOOD_RATE = \"10\s\"/g"
Question is how do I avoid this error?
/bin/sed: -e expression #1, char 28: unknown option to `s'
And is there a way to do a wild card match and replace with sed?
You have too many slashes, 4 when there should be 3. Use a different delimiter; comma (,), bang (!), hash (#), and at (#) are common alternatives.
sed -i "s,SYNFLOOD_RATE = \"100/s\",SYNFLOOD_RATE = \"10\s\",g"
Note that you have "100/s" in the original and "10s" (no slash) in the replacement. To actually insert a backslash, you'd need to enter 4 of them: 10\\\\s. Each pair will get reduced to a single by the shell and then the remaining double will be interpreted as a literal backslash by sed.
If you want to first grep then substitute :
sed -i '/SYNFLOOD_RATE = \"100/s/"\/SYNFLOOD_RATE = \"10\s\"/replacement/g'
But the delimiter can be anything else than /, see :
sed -i '/SYNFLOOD_RATE = "100/s#"/SYNFLOOD_RATE = "10\s"#replacement#g'
( the delimiter here is #)
Related
I have a string:
2021-05-27 10:40:50.678117 PID529270:TID 47545543550720:SID 1673488:TXID 786092740:QID 140: INFO:MEMCONTEXT:MemContext state: mem[cur/hi/max] = 9135 / 96586 / 96576 MB, VM[cur/hi/max] = 9161 / 21841178 / 100663296 MB
I want to get the number 9135 that first occurrence between '=' and '/', right now, my command as below, it works, but I don't think it's perfect:
sed -r 's/.* = ([0-9]+) .* = .*/\1 /'
Need a more neat one, please help advise.
You can use
sed -En 's~.*= ([0-9]+) /.*=.*~\1~p'
See the online demo.
An awk solution:
awk -F= '{gsub(/\/.*|[^0-9]/,"",$2);print $2}'
See this demo.
Details:
-En - E (or r as in your example) enables the POSIX ERE syntax and n suppresses the default line output
.*= ([0-9]+) /.*=.* - matches any text, = + space, captures one or more digits into Grou 1, then matches a space, /, then any text, = and again any text
\1 - replaces with Group 1 value
p - prints the result of the substitution.
Here, ~ are used as regex delimiters in order not to escape / in the pattern.
awk:
-F= - sets the input field separator to =
gsub(/\/.*|[^0-9]/,"",$2) - removes any non-digit or / and the rest of the string
print $2 - prints the modified Field 2 value.
You could also get the first match with grep using -P for Perl-compatible regular expressions.
grep -oP "^.*? = \K\d+(?= /)"
^ Start of string
.*? Match as least as possible chars
= Match space = and space
\K\d+ Forget what is matched so far
(?= /) Assert a space and / to the right
Output
9135
See a bash demo
Since you want the material between the first = and the first /, ignoring the spaces, you could use:
sed -E -e 's%^[^=]*= ([^/]*) /.*$%\1%'
This uses Extended Regular Expressions (ERE) (-E; -r also works with GNU sed), and searches from the start of the line for a sequence of 'not =' characters, the = character, a space, anything that's not a slash (which is remembered), another space, a slash, and anything that follows, replacing it all with what was remembered. The ^ and $ anchors aren't crucial; it will work the same without them. The % symbols are used instead of / because the searched-for pattern includes a /. If your sure there'll never be any spaces other than the first and last ones between the = and /, you can use [^ /]* in place of [^/]* and there should be some small (probably immeasurable) performance benefit.
This question already has answers here:
Can grep show only words that match search pattern?
(15 answers)
Closed 2 years ago.
I have a file with following text as below
classA = Something
classB = AB1234567
classC = Something more
classD = Something Else
Objective:
Using a shell script, I want to read the text which says AB1234567 from above complete text.
So to start, I can read the second line of the above text using following logic in my shell script:
secondLine=`sed -n '2p' my_file`;
echo $secondLine;
secondLine outputs classB = AB1234567. How do I extract AB1234567 from classB = AB1234567 in my shell script?
Question:
Considering the fact that AB is common in that particular part of the text all the files I deal with, how can I make sed to read all the numbers after AB?
Please note that classB = AB1234567 could end with a space or a newline. And I need to get this into a variable
Try:
sed '2{ s/^classB = \(AB[^ ]*\) *$/\1/;q } ;d' your_fileName
2 is the line number.
{ open a sed group command.
s/ substitute below match
^ is anchor for beginning of the line
\(...\) is known a capture group with \1 as its back-reference
[^ ]* means any character but not a space
\(AB[^ ]*\) capture AB followed by anything until first space seen but not spaces (back-reference is \1)
* means zero-or-more spaces
$ is anchor for end of the line
/ with below
\1 back-reference of above capture group
/ end of substitution
q quit to avoid reading rest of the file unnecessarily
} close group command.
d delete any other lines before seen line number 2.
get into variable:
your_variableName=$(sed '2{ s/^classB = \(AB[^ ]*\) *$/\1/;q } ;d' your_fileName)
Could you please try following, looks should be easy in awk. Considering you want to print 2nd line and print only digits in last field.
secondLine=$(awk 'FNR==2{sub(/[^0-9]*/,"",$NF);print $NF}' Input_file)
You may try this awk:
awk -F ' *= *' '$1 ~ /B$/ { print $2 }' file
AB1234567
I'm not 100% sure this is what you're looking for, but if you know there's only a single element in the file that starts with AB, this will get it into a variable:
$ cat sample.txt
classA = Something
classB = AB1234567
classC = Something more
classD = Something Else
$ x=$(perl -ne 'print if s/^.*\s+(AB\S+)\s*$/$1/' sample.txt)
$ echo "the variable is: $x"
the variable is: AB1234567
Explanation of the regex:
^ beginning of line
.* anything
\s+ any number of spaces
(AB\S+) anything that starts with AB followed by non-spaces
\s*$ Zero or more spaces followed by the end of the line.
I want to replace all slashes "/" between alphanumeric with backslash+slash "\/" apart from the last one on each string, e.g.
nocareNocare abc\/def/ghi/mno\/pq/r abc\/def\/ghi/mno\/pq/r
should become:
nocareNocare abc\/def\/ghi\/mno\/pq/r abc\/def\/ghi\/mno\/pq/r
I use:
sed 's/\(.*\)\([[:alnum:]]\)\/\([[:alnum:]]\)\(\S*\)\(\\\|\/\)/\1\2\\\/\3\4\//g'
Short explanation: match
any string + alnum + / + any non-white + / or \
But it only replace one case, so I need to run it 3 times to replace all 3 occurences. Looks like the first time it matches all the way to :
>nocareNocare abc\/def/ghi/mno\/pq/r abc\/def\/ghi/
instead of
>nocareNocare abc\/def/
sed -e :a -e 's|\([a-z0-9]\)/\([a-z0-9][^ ]*[a-z0-9]/[a-z0-9]\)|\1\\/\2|;ta' filename
Loosely translated, this says "replace a lone slash followed by some other stuff in the string, followed by another lone slash, with backslash-slash and that same stuff (and the second slash). And after making such a replacement, start over again."
You can use a perl command line solution based on the following regEx's
(?<!\\)
not preceded by a backslash
(?!\w+\s)
not followed by word characters terminating in whitespace
perl -pe 's;(?<!\\)/(?!\w+\s);\\/;g' file
nocareNocare abc\/def\/ghi\/mno\/pq/r abc\/def\/ghi\/mno\/pq/r
With GNU sed:
sed -E 's:([^\])/:\1\\/:g;s:\\/([^\]*( |$)):/\1:g' file
Two s command here:
s:([^\])/:\1\\/:g replace all / not preceded by a \ with \/
s:\\/([^\]*( |$)):/\1:g replace last \/ before space or end of line with /
I have the following sed command:
sed -n '/^out(/{n;p}' ${filename} | sed -n '/format/ s/.*format=//g; s/),$//gp; s/))$//gp'
I tried to do it as one line as in:
sed -n '/^out(/{n;}; /format/ s/.*format=//g; s/),$//gp; s/))$//gp' ${filename}
But that also display the lines I don't want (those that do not match).
What I have is a file with some strings as in:
entry(variable=value)),
format(variable=value)),
entry(variable=value)))
out(variable=value)),
format(variable=value)),
...
I just want the format lines that came right after the out entry. and remove those trailing )) or ),
You can use this sed command:
sed -nr '/^out[(]/ {n ; s/.*[(]([^)]+)[)].*/\1/p}' your_file
Once a out is found, it advanced to the next line (n) and uses the s command with p flag to extract only what is inside parenthesises.
Explanation:
I used [(] instead of \(. Outside brackets a ( usually means grouping, if you want a literal (, you need to escape it as \( or you can put it inside brackets. Most RE special characters dont need escaping when put inside brackets.
([^)]+) means a group (the "(" here are RE metacharacters not literal parenthesis) that consists of one or more (+) characters that are not (^) ) (literal closing parenthesis), the ^ inverts the character class [ ... ]
After some text manipulations I got the output: " 75 queen". I sent it like this:
..( 75 queen ).. | sed 's/ \([0-9]*\) \(q.*) /The word \2 with \1 appearances.'
For this code I got the error "sed: -e expression #1, char 66: unterminated `s' command.
What does it mean?
There are several issues that need to be solved in your sed expression:
The replace command must end with / plus any modifiers.
There are several regex "flavors" and sed uses the Basic POSIX regular expression, which means that () should be escaped in order to capture matching groups. Check this answer for details.
It seems you want to capture 75 and queen. To do that you need to specify that the first group should match any number of digits and the second group should capture q followed by any number of characters. * will match 0 or more of repetitions and + (that should be escaped) will match 1 or more repetitions.
Considering that, the following sed expression should do the trick:
echo '..( 75 queen )..' | sed 's/ \([0-9]\+\) \(q.*\) /The word \2 with \1 appearances./'