bash Linux shell 脚本 - 查找所有文件并对每个文件运行一个命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16341842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:19:57  来源:igfitidea点击:

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

linuxbashshell

提问by Argyrios Tzakas

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

我正在尝试将 Windows 批处理文件移植到 linux shell 脚本 (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 Metadataand then running the an XSLT transformation on each of these files. This takes 3 arguments

它的作用是找到所有包含文本元数据的.xml 文件,然后在这些文件中的每一个上运行 XSLT 转换。这需要 3 个参数

  • -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
  • -o 是输出文件(这将是一个与 .xml 同名的 .csv)
  • 接下来是目标文件
  • 最后一个参数是 .xsl 文件

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)

但这并不完全有效,因为我不知道如何使输出文件与 .xml 具有相同的名称(带有 .csv 扩展名)

Any tips?

有小费吗?

回答by harpun

You could process the results from findline by line and transform <file>.xmlinto <file>.csv:

您可以find逐行处理结果并转换<file>.xml<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.

如果文件名的路径/名称中有空格,这种简单的方法就会失败。

回答by voithos

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.

根据文档,字符串{}被当前文件名替换。这样,连同使用 Bash 的参数扩展,您应该能够将输出文件重命名为 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 .xmlextension, which is then replaced with .csv.

这里重要的一点是您在执行 Bash 时创建的 shell 参数。fname="{}"使用当前 XML 文件的内容创建一个新的 shell 参数。完成后,您可以使用参数扩展:扩展的${fname%.xml}条带,.xml然后将其替换为.csv.