Argyrios Tzakas
Argyrios Tzakas

Reputation: 325

Linux shell script - find all files and run a command on each one of them

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

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?

Upvotes: 0

Views: 5531

Answers (2)

voithos
voithos

Reputation: 70632

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.

Upvotes: 1

harpun
harpun

Reputation: 4110

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.

Upvotes: 4

Related Questions