Linux shell script - find all files and run a comm

2019-06-09 21:06发布

问题:

I'm trying to port a windows batch file to a linux shell script (bash).

Here is the part that is giving me some headache:

for /r %%G in (*Metadata*.xml) DO (
java -jar %SAXON%\saxon9he.jar -o:%%~nG.csv "%%G" %WORKDIR%\transformBQT.xsl)

What this does is find all .xml file containing the text Metadata and then running the an XSLT transformation on each of these files. This takes 3 arguments

  • -o is the output file (this will be a .csv with the same name as the .xml)
  • next is the target file
  • final argument is the .xsl file

I am thinking of using the following:

find /results/ -type f -name "*Metadata*.xml" -exec 
java -jar $SAXON/saxon9he.jar -o:??? {} $WORKDIR/transformXMI.xsl

but this doesn't quite work as I don't know how to make the output file have the same name as the .xml (with .csv extension)

Any tips?

回答1:

You could process the results from find line by line and transform <file>.xml into <file>.csv:

find /results/ -type f -name "*Metadata*.xml" | while read file; do java -jar $SAXON/saxon9h3.jar -o:${file%.xml}.csv $file $WORKDIR/transform.XMI.xsl; done

This simple approach fails in case the file names have spaces in their paths/names.



回答2:

Per the docs, the string {} is replaced by the current file name bring processed. With that, along with using Bash's parameter expansion, you should be able to rename the output files to CSV.

find /results/ -type f -name "*Metadata*.xml" -exec 
bash -c 'fname="{}"; java -jar $SAXON/saxon9he.jar -o:"${fname%.xml}.csv" "$fname" $WORKDIR/transformXMI.xsl' \;

The important bit here is the shell parameters that you create when you execute Bash. fname="{}" creates a new shell parameter with the contents of the current XML file. After you have that, you can use parameter expansions: ${fname%.xml} strips of the .xml extension, which is then replaced with .csv.



标签: linux bash shell