I am trying to append the lines
<configuration>
<jsp-configuration
display-source-fragment="false"
x-powered-by="false"/>
</configuration>
after line
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" enabled="false"/>
i am trying this command
sed -i '/<connector name="http" protocol="HTTP\/1.1" scheme="http" socket-binding="http" enabled="false"\/>/a <configuration>\n <jsp-configuration\n display-source-fragment=\"false\"\n x-powered-by=\"false\"/>\n </configuration>' abc.xml >output.xml
this is working fine for Unix but not working for solaris,giving command garbled error
The error may come from the space after your a command. Try remove it. Or, better: put your script in a file and write it like that:
/<connector name="http" protocol="HTTP\/1.1" scheme="http" socket-binding="http" enabled="false"\/>/a\
<configuration>\
<jsp-configuration\
display-source-fragment="false"\
x-powered-by="false"/>\
</configuration>
It's important that the very last character of the lines in your script be the backslash, except for the last of the appended lines. You name this file e.g. sedscr, and then:
sed -f sedscr abc.xml >output.xml
By the way, why did you use the option -i while redirecting the output to another file?
Related
This question already has answers here:
How to use sed to replace only the first occurrence in a file?
(25 answers)
Closed 7 years ago.
I have a file pom.xml, which needs to have the version with a SNAPSHOT appended to it. At times, the SNAPSHOT is missing, which results in the build failing. I'm trying to replace it with SNAPSHOT if it doesn't exist.
Actual:
<artifactId>package1</artifactId>
<version>1.0.0</version>
Desired:
<artifactId>package1</artifactId>
<version>1.0.0-SNAPSHOT</version>
Since the artifactId is not going to be the same across all the projects, I tried to search for a pattern that starts from </artifactId> to </version> and replace it with the SNAPSHOT text added to it. This has resulted in replacing the text till the last version available in pom.xml.
I've tried the following:
cat pom.xml | sed ':a;N;$!ba;1,/<\/artifactId>/s/<\/artifactId><version>[0-9]*.[0-9]*.[0-9]*<\/version>/<\/artifactId><version>1.0.0-SNAPSHOT<\/version>/g'
(Not working at all as it's unable to find the end of line).
cat common-pom.xml | sed ':a;N;$!ba;0,/<\/artifactId>/s/<\/artifactId>.*<\/version>/<\/artifactId><version>0.0.0-SNAPSHOT<\/version>/g'
(Is able to do the changes, but it's replacing all the text till the last version available in pom.xml).
How do I stop the replacement to the first occurrence in a multi line replacement?
If I understood the question correctly, this should work:
sed -r '
/<artifactId>/ {
n
s/(([0-9]+\.){2}[0-9])(<\/version>)/\1-SNAPSHOT\3/
}
' infile
You read the complete file into sed before starting with replacements. This just looks for a line with <artifactId>, reads the next line (n) and makes the replacement there.
Also, instead of using cat to pipe to sed, you can just give the file to be processed as an argument to sed.
This works also without -r, but then all parentheses and braces would have to be escaped.
Example file:
<artifactId>package1</artifactId>
<version>1.0.0</version> <-- should get SNAPSHOT
<artifactId>package1</artifactId>
<version>1.0.0-SNAPSHOT</version> <-- already has SNAPSHOT
Somethingelse
<version>1.0.0</version> <-- doesn't follow artifactId line
results in
<artifactId>package1</artifactId>
<version>1.0.0-SNAPSHOT</version>
<artifactId>package1</artifactId>
<version>1.0.0-SNAPSHOT</version>
Somethingelse
<version>1.0.0</version>
i want to inset multi lines befor last line in the file
that using sed , used the following sed attr
> sed -i '/\/web-app/r web.xml' inputerror.txt
last line in the file
</web-app>
inputerror.txt content as following
<error-page>
<error-code>404</error-code>
<location>/web/404</location>
</error-page>
nothing added to my web.xml any advise here
The following works in GNU sed:
sed '$s#^#<error-page>\n <error-code>404</error-code>\n <location>/web/404</location>\n</error-page>\n#' web.xml
But I don't know how portable \n is or how to make it read from a file.
I want to replace a URL present in an html file for the shortcut icon, using c. I use sed to replace the url but the command is giving an error as it can't read the icon even if the icon is present at the specified location.
If I manually replace the URL, it's working fine.
My command is:
sed -i '/<link id=/c\\<link id='test' rel='shortcut icon' href='path_of_icon' type='image/x-icon'/>' path_of_html_file
sed -i "s|<link id=|<link id='test' rel='shortcut icon' href='path_of_icon' type='image/x-icon'|" path_of_html_file
You use only ' so shell mix content and interpretation
you forget the first s for replacment order
you use / as separtor of pattern but /is also in your pattern
If you want to use sed 'change' command to replace whole line containing "link id=..." then why not putting it into a script file and source via -f ? That would help with quoting issue (I believe your error is due to quoting, as already mentioned):
s.sed:
/<link id=/c\
<link id='test' rel='shortcut icon' href='path_of_icon' type='image/x-icon'/>
then
sed -i -f s.sed path_of_html_file
It's perfectly possible doing that on command line, but everything that deals with quotes inside other quotes can get pretty much ugly on a cmdline.
I have a nant script that ...
1. takes the content of disc-file
2. assigns that content to a nant property
3. and then calls sqlcmd with a -v passing in that property containg the content of the disc file
4. inside the sql script the contents of the file should be used by a stored proc.
The problem is that when the content of the file contains a space the nant build stops with a "Invalid argument" issue
Anone know a way around this ?
The top part of the nant script is ...
<?xml version="1.0"?>
<!-- the main name of this project -->
<project name="Hops" default="all">
<!-- BuildHistory -->
<property name="buildHistoryContents" value="" />
<xmlpeek xpath="/" file="BuildNotes.xml" property="buildHistoryContents"></xmlpeek>
<!-- <echo message="${buildHistoryContents}" /> -->
<!-- ***************** -->
<target name="ExecSql">
<echo message="running sql script : ${SqlBuildScriptsDir}${sqlBuildFileName}" />
<exec program="${SqlCmd}" commandline="-S ${SqlServerInstanceName} -E -d HBus -i ${SqlBuildScriptsDir}${sqlBuildFileName} -v vSchemaVersion=${buildHistoryContents} " />
</target>
The sql script contains the line ...
exec lsp_SchemaVersionUpsert '1.4', N'$(vSchemaVersion)'
A disc file content that works is ...
<BuildNotes>
<Note>
<buildVer>HasNotSpace</buildVer>
</Note>
</BuildNotes>
A disc file content that does not works is ...
<BuildNotes>
<Note>
<buildVer>Has Space</buildVer>
</Note>
</BuildNotes>
The use of all this is pass xml build comments to a table logging version build history for the db schema.
Does anyone know an alternate method or know a way through this ?
The next part, added after Phillip Keeley correcty solved first part (the SPACE Problem)
I simplified the original task to simplify the question.
There is also a Quoted Attribute Problem ; xml quoted attributes cause the nant build to fail with "Invalid Argument".
eg this will cause nant to choke but removing the dt attribute will enable the nant build to succeed ...
<BuildNotes>
<Note>
<buildVer>1.4</buildVer>
<dateStarted>09/24/2009 11:25:42</dateStarted>
<Item dt="20091008" >SpacesAndNoQuotedAttribute</Item>
</Note>
</BuildNotes>
Any ideas ... ?
Your problem is (of course) in line
<exec program="${SqlCmd}" commandline="-S ${SqlServerInstanceName} -E -d HBus -i ${SqlBuildScriptsDir}${sqlBuildFileName} -v vSchemaVersion=${buildHistoryContents} " />
specifically, in
-v vSchemaVersion=${buildHistoryContents}
The NAnt expression replaces property ${buildHistoryContents} with the stored value--which will include any embedded spaces. Problem is, when calling SQLCMD (I"m assuming that's what ${SqlCmd} resolves to) from a command window, the values for any and all -v parameters are space delimited -- that is, the parser hits -v, reads the next characters through the "=" as the variable name, then reads all characters after the = and through the next space (or end of line) as the value to assign to the variable, and that embedded space will mess you up bigtime.
On the command line, the work-around is to wrap the variable value in quotes:
- v MyVariable=Hello World
becomes
- v MyVariable="Hello World"
That doesn't work here, because it's XML and you have to wrap the commandline attribute of the exec element with quotes... and embedded quotes will, once again, mess you up bigtime.
I believe the work-around here is to use XML macro substitution (I quite possibly have the formal titles of these concepts wrong) for those embedded quotes. This value should be
"
Which means that the following should work:
<exec program="${SqlCmd}" commandline="-S ${SqlServerInstanceName} -E -d HBus -i ${SqlBuildScriptsDir}${sqlBuildFileName} -v vSchemaVersion="${buildHistoryContents}" " />
Please try this and see -- I may have to do something like this myself some day soon.
I have NAnt script which as part of its project calls a batch file using the following task:
<target name="makeplane">
<exec program="C:\WINDOWS\system32\CMD.EXE"
commandline="/C ${make.file} > ${make.log}"
verbose="false"
workingdir="${make.dir}"
basedir="${make.dir}">
</exec>
<delete>
<fileset basedir="c:\">
<include name="program" />
</fileset>
</delete>
</target>
Unfortunately i dont have control over the contents on the batch file and it spews out a lot of garbage onto the screen which is of no use in the log. So to get around this im redirecting the output from the bat file to a text file using the
> ${make.log}
part which equates to "> log.txt".
This redirection seems to create a file called "program" on the C drive and messes up all sorts of services and windows generally doesnt like it. To get around this Im manually deleting this file after the bat file has executed.
The problem is i now need to run a similar task for another project entirely and if they run at the same time then the first will lock the file called "program" and the second will fail. Not exactly a great situation for Continuous integration.
I searched on the net but because the file is called program i get all sorts of rubbish results. Anyone got any ideas on a work around. I tried the output parameter on the exec task but the issue remains the same.
If the file path to the log contains spaces, one generally would want to surround the path in quotes. In order to do this in nant one can use the " entity.
It sounds like this is what's happening in your particular situation. Therefore, if you change your example to the following I think things should work as expected.
<target name="makeplane">
<exec program="C:\WINDOWS\system32\CMD.EXE"
commandline="/C ${make.file} > "${make.log}""
verbose="false"
workingdir="${make.dir}"
basedir="${make.dir}">
</exec>
</target>
Usually this happens because the script is trying to create a file with a long file name with space in it (c:\program files in your case), but it is not using quotes around the long file name.
Here is what I did. I think it is a bit cleaner for complex commands.
<property name="cmd.label" value="\${ss.previous.label}#$Project.SSPath" />
<echo message="Getting $Project.Name source code with label \${cmd.label}" />
<property name="cmd" value=""\${tfs.root}\tf.exe" get $Project.SSPath "/version:L\${cmd.label}" /force /recursive /noprompt"/>
<exec program="cmd.exe"
workingdir="\${shadow.dir}"
failonerror="true"
verbose="true">
<arg value="/c" />
<arg value=""\${cmd}"" />
<arg value="> nul" />
</exec>