I need to uncomment and edit this line using sed:
root#host:~# cat $CONF | grep "pm\.max_requests"
;pm.max_requests = 500
Tried this, but nothing worked:
root#host:~# sed -i "s/^;?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
root#host:~# sed -i "s/^\;?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
root#host:~# sed -i "s/^(;)?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
root#host:~# sed -i "s/^(;?)pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
Here's what did work:
root#host:~# sed -i "s/^;pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
Problem is, the command has to work even if a semicolon isn't there.
I know I can start with something like below, but I was hoping I can have it done all in one line.
sed -i "s/#;pm\.max_requests/pm.max_requests/g" ${CONF}
Checked if this is a duplicate, but all I could find was Removed semicolon from a line in php.ini using shell command
sed by default uses the Basic Regular Expressions (BRE) regex flavour which does not parse ? as the "0 or 1" quantifier. Your commands fail as they try to match an inexistant literal ? character.
Your alternatives are the following :
some implementations support \? as the "0 or 1" quantifier, although it's not POSIXly defined
sed -i "s/^;\?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
you can use the equivalent \{0,1\} quantifier
sed -i "s/^;\{0,1\}pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
You could use the * quantifier instead of ?, which would lead to possibly removing multiple consecutive ; characters
sed -i "s/^;*pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
you can switch to the Extended Regular Expressions (ERE) regex flavour, using sed -E for BSD sed or modern GNU sed and sed -r for older GNU sed. With this flavour, the ? quantifier will work as you expected it to.
sed -iE "s/^;?pm\.max_requests *= *[^ ]*/pm.max_requests = 512/" ${CONF}
Related
I want to execute some sed command for any line that matches either the and or or of multiple commands: e.g., sed '50,70/abc/d' would delete all lines in range 50,70 that match /abc/, or a way to do sed -e '10,20s/complicated/regex/' -e '30,40s/complicated/regex/ without having to retype s/compicated/regex/
Logical-and
The and part can be done with braces:
sed '50,70{/abc/d;}'
Further, braces can be nested for multiple and conditions.
(The above was tested under GNU sed. BSD sed may differ in small but frustrating details.)
Logical-or
The or part can be handled with branching:
sed -e '10,20{b cr;}' -e '30,40{b cr;}' -e b -e :cr -e 's/complicated/regex/' file
10,20{b cr;}
For all lines from 10 through 20, we branch to label cr
30,40{b cr;}
For all lines from 30 through 40, we branch to label cr
b
For all other lines, we skip the rest of the commands.
:cr
This marks the label cr
s/complicated/regex/
This performs the substitution on lines which branched to cr.
With GNU sed, the syntax for the above can be shortened a bit to:
sed '10,20{b cr}; 30,40{b cr}; b; :cr; s/complicated/regex/' file
To delete lines from 10 to 20 and 30 to 40 matching your complicated regex with GNU sed:
sed -e '10,20bA;30,40bA;b;:A;s/complicated/regex/;d' file
or:
sed -e '10,20bA' -e '30,40bA' -e 'b;:A;s/complicated/regex/;d' file
bA: jump to label :A
b: a jump without label -> jump to end of script
d: delete line
I don't think sed has the facility for multiple selection criteria, my advice would be to step up to awk, where you can do something like:
awk 'NR >= 50 && NR <= 70 && /abc/ {next} {print}' inputFile
awk '(NR >= 10 and NR <= 20) || (NR >= 30 && NR <= 40) {
sub("from-regex", "to-string", $0); print }'
sed is excellent for simple substitutions on individual lines but for anything else just use awk for clarity, robustness, portability, maintainability, etc...
awk '
(NR>=50 && NR<=70) && /abc/ { next }
(NR>=10 && NR<=20) || (NR>=30 && NR<=40) { sub(/complicated/,"regex") }
{ print }
' file
Problem statement:
change every user agent that does not match A2PC or GENCOM with the user agent PROHIBITED and keep GENCOM and A2PC unchanged
Expression:
echo \"GENCOM\" | sed -r -e 's/(^((?!A2PC)(?!GENCOM).)*$)/PROHIBITED/g'
error:
sed: -e expression #1, char 41: Invalid preceding regular expression
I removed -r then error not thrown but its not working
echo \"GENDFGGH\" | sed -e 's/(^((?!A2PC)(?!GENCOM).)*$)/PROHIBITED/g'
"GENDFGGH"
Please help me for this solution
First look for your pattern and then do the sub:
# echo \"GENCsOM\" | sed -e '/^"\(GENCOM\|A2PC\)"$/! s/^.*$/PROHIBITED/'
PROHIBITED
# echo \"GENCOM\" | sed -e '/^"\(GENCOM\|A2PC\)"$/! s/^.*$/PROHIBITED/'
"GENCOM"
sed '/A2PC/ !{
/GENCOM/ ! {
s/$/PROHIBITED/
}
}' YourFile
double exclusion than a change, posix compliant
I'm trying to port a GNU sed command to BSD sed (in OSX). The command is:
cat -- "$1" | sed -n -e "\${/^#/H;x;/${tapPrintTapOutputSedPattern}/p;}" \
-e "/${tapPrintTapOutputSedPattern}/{x;/${tapPrintTapOutputSedPattern}/p;b;}" \
-e "/^#/{H;b;}" \
-e "x;/${tapPrintTapOutputSedPattern}/p" \
-e "/^Bail out!/q"
It works on GNU sed, but BSD sed gives this error:
sed: 2: "/^Bail out!/q
": unexpected EOF (pending }'s)
This is the command after the variable expansions, in case it's relevant:
cat -- "test021.tap" | sed -n \
-e "\${/^#/H;x;/^not ok\|^ok \([0-9]\+ \)\?# [tT][oO][dD][oO]\|^Bail out!/p;}" \
-e "/^not ok\|^ok \([0-9]\+ \)\?# [tT][oO][dD][oO]\|^Bail out!/{x;/^not ok\|^ok \([0-9]\+ \)\?# [tT][oO][dD][oO]\|^Bail out!/p;b;}" \
-e "/^#/{H;b;}" \
-e "x;/^not ok\|^ok \([0-9]\+ \)\?# [tT][oO][dD][oO]\|^Bail out!/p" \
-e "/^Bail out!/q"
Any ideas about why/how to fix it?
Cheers!
Try using newlines instead of a semicolons, at least before the branch commands (b) in the statements. See if this works:
sed -n "
\${
/^#/H
x
/${tapPrintTapOutputSedPattern}/p
}
/${tapPrintTapOutputSedPattern}/{
x
/${tapPrintTapOutputSedPattern}/p
b
}
/^#/{
H
b
}
x
/${tapPrintTapOutputSedPattern}/p
/^Bail out!/q
" "$1"
I have a file which looks like below:
memory=500G
brand=HP
color=black
battery=5 hours
For every line, I want to remove everything after = and also the =.
Eventually, I want to get something like:
memory:brand:color:battery:
(All on one line with colons after every word)
Is there a one-line sed command that I can use?
sed -e ':a;N;$!ba;s/=.\+\n\?/:/mg' /my/file
Adapted from this fine answer.
To be frank, however, I'd find something like this more readable:
cut -d = -f 1 /my/file | tr \\n :
Here's one way using GNU awk:
awk -F= '{ printf "%s:", $1 } END { printf "\n" }' file.txt
Result:
memory:brand:color:battery:
If you don't want a colon after the last word, you can use GNU sed like this:
sed -n 's/=.*//; H; $ { g; s/\n//; s/\n/:/g; p }' file.txt
Result:
memory:brand:color:battery
This might work for you (GNU sed):
sed -i ':a;$!N;s/=[^\n]*\n\?/:/;ta' file
perl -F= -ane '{print $F[0].":"}' your_file
tested below:
> cat temp
abc=def,100,200,dasdas
dasd=dsfsf,2312,123,
adasa=sdffs,1312,1231212,adsdasdasd
qeweqw=das,13123,13,asdadasds
dsadsaa=asdd,12312,123
> perl -F= -ane '{print $F[0].":"}' temp
abc:dasd:adasa:qeweqw:dsadsaa:
My command is
First step:
sed 's/([a-z]+)(\=.*)/\1:/g' Filename |cat >a
cat a
memory:
brand:
color:
battery:
Second step:
sed -e 'N;s/\n//' a | sed -e 'N;s/\n//'
My output is
memory:brand:color:battery:
I have a file called data.txt.
I want to add the current date, or time, or both to the beginning or end of each line.
I have tried this:
awk -v v1=$var ' { printf("%s,%s\n", $0, v1) } ' data.txt > data.txt
I have tried this:
sed "s/$/,$var/" data.txt
Nothing works.
Can someone help me out here?
How about :
cat filename | sed "s/$/ `date`/"
The problem with this
awk -v v1=$var ' { printf("%s,%s\n", $0, v1) } ' data.txt > data.txt
is that the > redirection happens first, and the shell truncates the file. Only then does the shell exec awk, which then reads an empty file.
Choose one of these:
sed -i "s/\$/ $var/" data.txt
awk -v "date=$var" '{print $0, date}' data.txt > tmpfile && mv tmpfile data.txt
However, does your $var contain slashes (such as "10/04/2011 12:34") ? If yes, then choose a different delimiter for sed's s/// command: sed -i "s#\$# $var#" data.txt