4

I have a structure of a project in my git repository and would like to run a shell command in git bash to replace all the > with >\n (LF). I tried the following command:

find . -name '*.xml' -exec sh -c 'sed 's/>/>\n/g "$0"' '{}' ';'

meaning to replace the above sets (> with >\n) in all xml files found in my project.

I don't know what I am doing wrong since I land in the editor with cursor ">"... (just making it pretty in an editor - e.g. Note++ is easy with plugins for XMLTools but I want my files altered to have in them the LF after each XML tag)

When I write the command for a file only - it works nice:

$ sed 's/>/>\n/g' MyFile.xml
Inian
  • 12,472
  • 1
  • 35
  • 52
Teo
  • 143
  • 6
  • 2
    Did you try running `xmlstarlet fo MyFile.xml`? – Kusalananda Jan 09 '20 at 12:58
  • 1
    Teo, you've an odd number of single quotes in that line so it can't run. Please double-check what you've shown us. If this is the issue and you've been getting errors when you try to run it, please tell us! – roaima Jan 09 '20 at 13:14
  • @roaima:I tried to simplify my command: find . -name '*.xml' -print0 | xargs -0 -I '{}' sed 's/>/>\n/g ' '{}' It worked on the Git Bash but nothing happend in the files... – Teo Jan 09 '20 at 17:02
  • Of course not. You didn't ask that ↑ to change anything. But your _question as posted_ has a syntax error on the `find ...` line. Please address that or make it clear that the reason it's not working for you is that you're getting an error that you can't fix. – roaima Jan 09 '20 at 17:07
  • Thanks @roaima:I tried to simplify my command: find . -name '*.xml' -print0 | xargs -0 -I '{}' sed 's/>/>\n/g ' '{}' It worked on the Git Bash but nothing happend in the files... Still stuck! I would be thankful if you could show me how to correc my statements because I am new to Linux and don't have a clue how to imbedd quotes in quotes - as in my original sed statement. – Teo Jan 09 '20 at 17:13
  • So is the problem that you're getting an error when you try to run it? If so PLEASE TELL US !!! – roaima Jan 09 '20 at 17:19
  • I don't know what I am doing wrong since I land in the editor with cursor ">". – Teo Jan 09 '20 at 17:24
  • Editor? What editor? – roaima Jan 09 '20 at 17:25
  • I suppose it is from sed(?) this cursor ">" - I exit from there with CTRL-C to reach again the "$" - cursor from git bash – Teo Jan 10 '20 at 15:49
  • 1
    Oh I see. No, that's the secondary prompt from your shell. In this instance it's because you have an odd number of quoting characters in your command, so the shell needs the closing quote to complete your command. – roaima Jan 15 '20 at 23:09

1 Answers1

10

It's a bad idea to use sed for this, what you seems to do is to format the XML file.

It's a simple task for any XML parser, ex :

xmllint --format file.xml

This utility is often installed by default on GNU Linux, or with the package libxml2

or

xmlstarlet format file.xml
Gilles Quénot
  • 31,569
  • 7
  • 64
  • 82
  • I work with Git Bash in windows: Message: bash: "xmlstarlet: command not found" – Teo Jan 09 '20 at 17:09
  • Because the command is not installed. AFAIK you can install it for windows. Is `xmllint` is installed ? – Gilles Quénot Jan 09 '20 at 17:12
  • I work with Git Bash in windows: Message: bash: "xmlstarlet: command not found" (same with xmllint) Could you please elaborate on why is a bad ideea to use sed? And I wonder how to install xmllint in my environment - Git Bash for windows... – Teo Jan 09 '20 at 17:22
  • 6
    "Why is it a bad idea" -- good discussion here: [Why it's not possible to use regex to parse HTML/XML: a formal explanation in layman's terms](https://stackoverflow.com/questions/6751105/why-its-not-possible-to-use-regex-to-parse-html-xml-a-formal-explanation-in-la) – glenn jackman Jan 09 '20 at 17:33
  • 1
    https://sourceforge.net/projects/xmlstar/files/xmlstarlet/1.6.1/xmlstarlet-1.6.1-win32.zip/download – Gilles Quénot Jan 09 '20 at 17:44
  • 1
    'why it's a bad idea': check a post that I wrote yesterday here: https://unix.stackexchange.com/questions/561017/how-to-remove-nodes-from-xml-file-as-command-line/561018#561018 – Gilles Quénot Jan 09 '20 at 23:35
  • @Giles Quenot - Thanks for the lessons: - the WHY not use regex to parse XML (good deep discution) - the link to download xmlstarlet from sourceforge.net - it worked except that now I am struggling to use the command "xml" and it seems to work nice with other commands (e.g. ls) and even with fo but I get a nice xml with LF inserted only on the terminal since my question was (and I am still puzzled) how to alter all my xml files in a subdirectory! I tried it for a file and the file remains unaltered (without the LF inserted!...) – Teo Jan 13 '20 at 12:58
  • SOLVED - worked well with: xml format source.xml >dest.xml (for one file) I still don't know how to do it for all the .xml files in the subfolders...(?) – Teo Jan 13 '20 at 13:21
  • Like this: `find . -type f -iname '*.xml' -exec bash -c 'xml format "$1" > /tmp/xml.xml && mv /tmp/xml.xml "$1"' -- {} \;` – Gilles Quénot Jan 13 '20 at 21:14
  • @Gilles - many Thanks! You sent me on the right track on learning shell commands and sintax! Your comment are pro and you seem to be a good teacher. I ran your command and it looks good - it works properly, but I am not sure what you are doing - i.e. I don't fully understand the end of your command: after &&... I just gues that "&&" concatenates two shell commands (here mv after xml) but what really "-- {} \" does must be somehow connected with removing the tmp subdir (which I just noticed that dissapeared! - wow). – Teo Jan 14 '20 at 08:19
  • If you can please give me some hints about that. ( I was struggling yesterday with find and did unsuccessfully my best; #find . -type f -name '*.tmp' -print0 |xargs -0 -I '{}' mv '{}' '{%.tmp}' ->but erases all tmp files!) – Teo Jan 14 '20 at 08:20
  • Teo: Feel free to mail me with your request – Gilles Quénot Jan 14 '20 at 10:37