Shell脚本循环遍历文件

时间:2015-12-10 10:57:22

标签: 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等效。

非常感谢大家的评论,尤其是查尔斯和阿列克谢。我使用的最终解决方案是由以下Alexei提供的。我似乎没有能力在这里进行投票,或者我会这样做。

1 个答案:

答案 0 :(得分:1)

剧情简介:

  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评论
  5. 放入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;
    
相关问题