I have a variables that needs to be modified so that minutes %M is added. I know the sed command and it is working as expected.
# cat mysed.txt
myfirstfile="comany$mydb`date +'%d-%b-%Y-%H'`.sql"
# sed -i 's/\%H/\%H-\%M/' mysed.txt
# cat mysed.txt
myfirstfile="company$mydb`date +'%d-%b-%Y-%H-%M'`.sql"
But if I run the same sed command again, it will add %M again as follows.
# sed -i 's/\%H/\%H-\%M/' mysed.txt
# cat mysed.txt
myfirstfile="company$mydb`date +'%d-%b-%Y-%H-%M-%M'`.sql"
I need a sed command that should add the minutes %M only once even if sed command is executed twice (by mistake)
# sed -i "s/%H'/%H-%M'/" mysed.txt
This should work. This way it will only do the replacement if there is a quote mark next to the %H.
Test if it is present before substituting:
sed '/%H-%M/! s/%H/%H-%M/' mysed.txt
Btw. % does not need to be escaped.
I believe below command will work fine.Please replace test.dat file with your file name.
cat test.dat|sed "s/\%H\'/\%H\-\%M\'/" > test.dat
Without cat command
sed -i "s/\%H\'/\%H\-\%M\'/" test.dat > test.dat
Cheers!
Related
I already know that sed uses own approach to deal with single quote but I think it still possible to use it in my automation script.
I had to replace value of fingerprint in Saltstack config file.
Current value:
#master_finger: ''
Target value
master_finger: 'some:value'
My current command which doesn't work:
$ sed -i 's/#master_finger: ''/master_finger: 'some:value'/g' /etc/salt/minion
returns:
master_finger: some:value''
How can I solve this?
just use the double quotes to enclose the script.
$ echo "#master_finger: ''" | sed "s/#master_finger: ''/master_finger: 'some:value'/"
master_finger: 'some:value'
It's not sed that's making handling of 's difficult, it's the shell because the shell does not allow 's within any '-quoted string, including scripts.
You could save the sed script in a file and run it with -f or use a here document:
$ sed -f- file <<'EOF'
s/#master_finger: ''/master_finger: 'some:value'/g
EOF
master_finger: 'some:value'
To see the difference between the above and #karakfas suggestion:
$ sed -f- file <<'EOF'
s/#master_finger: ''/master_finger: '$(date)'/g
EOF
master_finger: '$(date)'
$ sed "s/#master_finger: ''/master_finger: '$(date)'/" file
master_finger: 'Sun Feb 14 06:50:43 CST 2021'
and imagine if date was replace by rm -rf * or something worse.
Also consider:
$ sed 's/#master_finger: '\'\''/master_finger: '\''$(date)'\''/' file
master_finger: '$(date)'
sed inplace change on a file is not working inside Make object.
I want to replace a line in a file with sed called in a make object. But it does not seem to be working. How can I fix this?
change_generics:
ifeq ($(run_TESTNAME), diagnostics)
ifeq ($(run_TESTCASE), 1)
sed -i -e "s/SIM_MULTI\==[a-z,A-Z]*/SIM_MULTI=TRUE/" ./generics.f
else ifeq ($(TESTCASE), 2)
sed -i -e "s/SIM_MISSED\==[a-z,A-Z]*/SIM_MISSED=TRUE/" ./generics.f
endif
endif
I would like the generics.f file changed with that one line change. But it remains the same as the original. The sed command works outside make.
I can't reproduce this using GNU sed 4.2.2 and GNU make 3.82, or at least, I can't reproduce any scenario where the same sed command works from the command line but not in a Makefile.
Simpler Makefile:
all:
# Contrived just so I can test your 2 sed commands.
sed -i -e "s/SIM_MULTI\==[a-z,A-Z]*/SIM_MULTI=TRUE/" ./generics.f
sed -i -e "s/SIM_MISSED\==[a-z,A-Z]*/SIM_MISSED=TRUE/" ./generics.f
Sample file content in generics.f:
SIM_MULTI=foo
SIM_MISSED=bar
Testing:
$ make all
sed -i -e "s/SIM_MULTI\==[a-z,A-Z]*/SIM_MULTI=TRUE/" ./generics.f
sed -i -e "s/SIM_MISSED\==[a-z,A-Z]*/SIM_MISSED=TRUE/" ./generics.f
Confirmed that both sed commands fail to edit a file with this content.
To fix:
Probably, you need to simply remove the \= from your regular expression. The backslash there has no effect, and causes your regex to simply match two equals signs ==. Thus this works:
all:
sed -i 's/SIM_MULTI=[a-zA-Z]*/SIM_MULTI=TRUE/' ./generics.f
sed -i 's/SIM_MISSED=[a-zA-Z]*/SIM_MISSED=TRUE/' ./generics.f
Testing:
$ make all
sed -i 's/SIM_MULTI=[a-zA-Z]*/SIM_MULTI=TRUE/' ./generics.f
sed -i 's/SIM_MISSED=[a-zA-Z]*/SIM_MISSED=TRUE/' ./generics.f
$ cat generics.f
SIM_MULTI=TRUE
SIM_MISSED=TRUE
Further explanation:
There is no need to specify -e there.
There is no need to enclose the script in double quotes, which is riskier because it allows the contents to be modified by the shell.
The bug appears to be \= and I deleted those characters, as mentioned above.
Note that I removed the comma , as well in [a-z,A-Z]. I think that probably isn't what you meant, and it would cause a class of characters including a-z, A-Z and a comma , to be matched by the regex. (And if it is what you mean, you might consider writing it as [a-zA-Z,] as that would be less confusing.)
If this has not resolved your issue, I would need to know things like:
What is the version of your sed.
What is the contents in generics.f.
POSIX/GNU sed have c for "change":
sed -i '/SIM_MULTI=/c\SIM_MULTI=TRUE'
sed -i '/SIM_MISSED=/c\SIM_MISSED=TRUE'
I have the following line in a file:
$app-assets:"/assets/";
I am trying to use sed in the terminal to overwrite that line to read as follows:
$app-assets:"http://www.example.com/assets/";
I have tried the following but it does not work:
sed -i \'\' -e \'s/app-assets:"/assets/"/app-assets:"http://www.example.com/assets/"/g\' myfile.txt
I am fine using Perl if easier.
Use the following sed approach:
sed -i 's~\(\$app-assets:"\)\(/assets/\)"~\1http://www.example.com\2"~' myfile.txt
~ here is treated as sed subcommand separator
sed 's/app-assets:\"\/assets\/\";/app-assets:\"http:\/\/www\.example\.com\/assets\/\";/g' filename
I'm requesting help with a very simple script...
#!/usr/bin/sed -f
sed '/11,yahoo/d'
sed '/2506,stackover flow/d'
sed '/2536,reddit/d'
Just need it to remove three matches that account for 18408 in my file, data.csv
% sed -f remove.sed < data.csv
sed: 3: remove.sed: unterminated substitute pattern
Doing these same lines individually is no problem at all, so what am I doing wrong with this?
Using freeBSD 10.1 and its implementation of sed, if that matters.
This, being a sed script, should not have "sed" at each line.
Either change it to:
#!/usr/bin/sed -f
/11,yahoo/d
/2506,stackover flow/d
/2536,reddit/d
Or to
#!/bin/sh
sed -e /11,yahoo/d \
-e /2506,stackover flow/d \
-e /2536,reddit/d
Due to the know prob of mocha-lcov-mocha breaking file paths, I need to fix the current output paths that looks like this:
SF:Vis/test-Guid.coffee
SF:Vis/Guid.coffee
SF:Vis/test-Vis-Edge.coffee
SF:Vis/Vis-Edge.coffee
into
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
I'm not very good with sed, but I got it to work using:
mocha -R mocha-lcov-reporter _coverage/test --recursive | sed 's,SF:,SF:src/,' | sed s',SF.*test.*,SF:test//&,' | sed s',/SF:,,' | sed s',test/src,test,' | ./node_modules/coveralls/bin/coveralls.js
which is basically doing 4 sed commands in sequence
sed 's,SF:,SF:src/,'
sed s',SF.*test.*,SF:test//&,'
sed s',/SF:,,'
sed s',test/src,test,'
my question is if there is a way to do with this one sed command, or use another osx/linux command line tool
Initially put "src/" after every ":" and then if "test" is found on the line replace "src" with "test":
$ sed 's,:,:src/,;/test/s,src,test,' file
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
You could put all the sed commands in a file, one line per command, and just use "sed -e script". But if you just want it on a single command-line, separate with semicolons. This works for me:
sed 's,SF:,SF:src/,;s,SF.*test.*,SF:test//&,;s,SF:,,;s,test/src/,test,'
sed command
sed '\#test#!{s#SF:Vis/#SF:src/Vis/#g};\#SF:Vis/test#{s#SF:Vis/test#SF:test/Vis/test#g};' my_file
Here is an awk version:
awk -F: '/SF/ {$0=$1FS (/test/?"test/":"src/")$2}1' file
SF:test/Vis/test-Guid.coffee
SF:src/Vis/Guid.coffee
SF:test/Vis/test-Vis-Edge.coffee
SF:src/Vis/Vis-Edge.coffee
How it works:
awk -F: ' # Set field separator to ":"
/SF/{ # Does line start with "SF"?
$0=$1FS (/test/?"test/":"src/")$2 # Recreat String by adding "test" if line contains "test", else "src"
}
1 # Print all lines
' file # read the file