xml - Shell 脚本循环遍历文件

标签 xml bash shell sh

我正在尝试使用简单的 shell 脚本自动将 XML 文件解析到 MySQL。 解析器工作正常,它接受 ABC123.xml 并输出 ABC123.sql。

我尝试编写一个 shell 脚本来获取目录中的文件,并将文件名传递给脚本。在文件中,前缀 ABC 始终存在,但数字会发生变化,并且不连续。所以我想要的是,例如,获取文件 ABC*.xml 并输出 ABC*.sql。

这是我所拥有的:

for file in $(ABC*.xml); do

temp="java -cp XMLParser-2.0-SNAPSHOT.jar:$MYSQL_CJ Engine.xmlparsers.Parser 
-url='jdbc:mysql://localhost/DBNAME?useUnicode=true&characterEncoding=UTF-8&user=USERNAME&password=PASSWORD' 
-file='/mnt/volume/SQL/$file.sql' /mnt/volume/XML/$file.xml"
eval $temp
done

解析器运行,我得到一个输出文件 ABC*.sql,没有其他内容。

我也尝试过

for file in *; do

这只是处理脚本目录中的所有文件

之前我运行了一个脚本,该脚本可以完美地处理具有连续后缀的文件,解决方案是:

for i in $( seq 1 500 ); do

temp="java -cp XMLParser-2.0-SNAPSHOT.jar:$MYSQL_CJ Engine.xmlparsers.Parser 
-url='jdbc:mysql://localhost/DBNAME?useUnicode=true&characterEncoding=UTF-8&user=USERNAME&password=PASSWORD' 
-file='/mnt/volume/SQL/ABC-$i.sql' /mnt/volume/XML/ABC-$i.xml"
eval $temp
done

任何想法都会有帮助。 谢谢

更新

非常感谢您的初步评论。

我试过$(ls ABC*.xml)正如 squeamishossifrage 建议的那样,但这给出了错误 ls: cannot access ABC*.xml: No such file or directory .

我很想直接上传到 MySQL,但是每个 XML 文件都有几十个元素,其中有许多子元素,这些元素被分解到不同的表中。

根据user1934428请求,该变量的功能如下:

假设我有三个 XML 文件:

ABC12345.xml
ABC98172.xml
ABC7211891.xml

解析器应该读取这些文件并将元素解析为 SQL 并输出

ABC12345.sql
ABC98172.sql
ABC7211891.sql

我希望 shell 脚本做的是,对于此目录中的所有 XML 文件,将它们提供给脚本,其中 $file.xml是输入文件,$file.sql是输出文件。

正如我上面提到的,例如,如果我有带有连续后缀的文件,这将非常有效

ABC-1.xml
ABC-2.xml
ABC-3.xml

使用for i in $( seq 1 3 ); do输出

ABC-1.sql
ABC-2.sql
ABC-3.sql

哪里ABC-$i.xml是输入和 ABC-$i.sql是输出。

我不知道如何制作相当于 for i in $( seq 1 3 ); do 的内容当我不知道文件名时。

解决方案

非常感谢大家的评论,特别是 Charles 和 Alexei。我使用的最终解决方案是下面 Alexei 提供的。我似乎没有能力在这里投票,否则我就会这么做。

最佳答案

概要:

  1. 使用 shopt -s nullglob 阻止文字 ABC*.xml 匹配。如果您的模式不匹配,则不会返回任何内容,并且表明 ABC 不是此搜索空间中最左边的常用共享字符串。 Ref

  2. 在 for 循环中,使用 base="${file%.*}"; 提取名称。 Ref

  3. 如果您希望单引号出现在 eval 中,请转义它们:\'

  4. 不要使用 eval(如果可能)

    • 直接执行命令。在参数中传递的变量应展开("$MYSQL_CJ""$base.xml")。 Double quotes to prevent odd behavior 。不适用于 ~(例如 "~/$base.xml"),如果需要可以使用 ~/$base.xml,但有上述警告。
    • 查看 Charles Duffy 评论

放入 shell 脚本中或从 bash 运行(将 /path/to/ 替换为 ABC 文件的绝对路径):

FILES=/mnt/volume/XML/ABC*.xml;
shopt -s nullglob; #don't match ABC*.xml literal
for file in $FILES; do
 filename =$(basename "$file");
 filename="${filename%.*}";
 java -cp "XMLParser-2.0-SNAPSHOT.jar:$MYSQL_CJ" Engine.xmlparsers.Parser \
  -url="jdbc:mysql://localhost/DBNAME?useUnicode=true&characterEncoding=UTF-8&user=USERNAME&password=PASSWORD" \
  -file="/mnt/volume/SQL/$filename.sql" "$file";
 done; \
shopt -u nullglob;  #disable nullglob

测试:

touch Harrison_Wells.xml; 
bash; 
shopt -s nullglob;
for file in Harrison_*.xml; do 
  filename="${file%.*}"; 
  echo "The 'Reverse-Flash' is $filename.are_we_right"; 
  done; \
shopt -u nullglob;

关于xml - Shell 脚本循环遍历文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34200126/

相关文章:

bash -/etc/init.d/centos 和 debian 中的函数和操作

linux - 如何创建递归嵌套的 zip 文件

bash - Bash 脚本中的多个 If 语句

html - 根据条件为 HTML 表格列分配颜色

windows - 如何使用 ANT 从 Windows XP 系统执行 UNIX 命令

java - Jaxb,避免重复的 xml 标签

xml - 如何使用 xpath 选择命名空间定义标记

linux - 去除转义字符的 ASCII 文本(ls 输出重定向)

php - Xpath setAttribute fatal error 调用成员函数setAttribute

android - 编辑 Android XML 文件时,Eclipse 缺少图形布局和源选项卡