-1

I have a file content as shown below. If a line has ".idt" word, then I need to check if there is a file path preceding it (eg: /bin/dir/test/abcdef.idt). If yes, then remove the file path and keep only the actual file name (eg: abcdef.idt). The idt file need not always be mentioned with absolute path; it can just be the filename alone. There can be only one idt file mentioned in a line (between one < file>..< /file> tag). This needs to be done for all the files in a directory.

In the below example, see the 3 lines having emptest1.idt, emptest2.idt & emptest3.idt

Sample Input file content (xml file):

<Application Name="empBnf" ServiceType="SOAP" BitMode="32" Path="/test/bin"/>
<FileList>
    <File>/test/src/repos/emp.deploy/emptest1.idt</File>
    <File>emptest2.idt</File>
    <File>
          /test/src/repos/emp.deploy/emptest3.idt
     </File>
    <File>/test/src/repos/emp.deploy/emptest.wsdl</File>
</FileList>
<Service Qualifier="http://www.mytest.com/test/empbnf" Name="/test/src/repos/empBnf" XManagement="Container">
    <Operation>Operation</Operation>
</Service>

The output has to be:

<Application Name="empBnf" ServiceType="SOAP" BitMode="32" Path="/test/bin"/>
<FileList>
    <File>emptest1.idt</File>
    <File>emptest2.idt</File>
    <File>
          emptest3.idt
     </File>
    <File>/test/src/repos/emp.deploy/emptest.wsdl</File>
</FileList>
<Service Qualifier="http://www.mytest.com/test/empbnf" Name="/test/src/repos/empBnf" XManagement="Container">
    <Operation>Operation</Operation>
</Service>

  • (1) Will the file paths always be absolute pathnames?  (2) Can there be multiple filenames on the same line?  (3) Can you ever have </File>…<File>/some/path/emptest2.idt on the same line?  (4) What have you tried?    Please do not respond in comments; edit your question to make it clearer and more complete. – G-Man Jan 3 at 10:24
  • Thank You, G-Man!! Per your suggestion, I have provided the information in the question. I am new to linux shell script; so came through sed command by going through google but none of mine worked... sed -n, sed-s. – viki143 Jan 3 at 10:55
2

You could use:

sed -i -E -e 's/(\/.*\/)(.*\.idt)/\2/' file_list

This performs an in-place (-i) replacement of all /..../filename.idt filepaths with filename.idt ("all" as in: the first occurrence on each line of a certain file). If there is no absolute path preceding the filename, the regex does not match, and nothing happens. The file_list can be replaced with an *.xml or the like at your command prompt. You may want to try running the command without the -i option first, to see the output before writing it to disk.

2

Assuming the XML is well formed, the following will remove the string /test/src/repos/emp.deploy/ from the values of each File node that contains that string and the string .idt using XMLStarlet (or rather, it leaves the bit of the value that occurs after the path):

xmlstarlet ed -u '//File[contains(., "/test/src/repos/emp.deploy/") and contains(., ".idt")]' \
              -x 'substring-after(., "/test/src/repos/emp.deploy/")' file.xml

Adding a root node to your example document and running the above command generates

<?xml version="1.0"?>
<root>
  <Application Name="empBnf" ServiceType="SOAP" BitMode="32" Path="/test/bin"/>
  <FileList>
    <File>emptest1.idt</File>
    <File>emptest2.idt</File>
    <File>emptest3.idt
     </File>
    <File>/test/src/repos/emp.deploy/emptest.wsdl</File>
  </FileList>
  <Service Qualifier="http://www.mytest.com/test/empbnf" Name="/test/src/repos/empBnf" XManagement="Container">
    <Operation>Operation</Operation>
  </Service>
</root>

It would be even neater if the following worked:

xmlstrlet ed -u '//File[contains(., ".idt")]' \
             -x 'replace(.,".*/","")' file.xml

... but XMLStarlet (on my system) doesn't seem to want to know about the replace() function.

0
I Have used below method

command: sed '/idt/s/\/test.*emp.deploy\///g' file

output

sed '/idt/s/\/test.*emp.deploy\///g' file1
<Application Name="empBnf" ServiceType="SOAP" BitMode="32" Path="/test/bin"/>
<FileList>
    <File>emptest1.idt</File>
    <File>emptest2.idt</File>
    <File>
          emptest3.idt
     </File>
    <File>/test/src/repos/emp.deploy/emptest.wsdl</File>
</FileList>
<Service Qualifier="http://www.mytest.com/test/empbnf" Name="/test/src/repos/empBnf" XManagement="Container">
    <Operation>Operation</Operation>
</Service>
  • 1
    I'd recommend a more-general replacement, instead of requiring "test.*emp.deploy", as the OP said "if there is a file path preceding it (eg: /bin/dir/test/abcdef.idt). If yes, then remove the file path" -- I wouldn't assume that every path matches "test.*emp.deploy" – Jeff Schaller Jan 3 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.