我正在尝试使用简单的 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 提供的。我似乎没有能力在这里投票,否则我就会这么做。
最佳答案
概要:
使用
shopt -s nullglob
阻止文字 ABC*.xml 匹配。如果您的模式不匹配,则不会返回任何内容,并且表明 ABC 不是此搜索空间中最左边的常用共享字符串。 Ref在 for 循环中,使用
base="${file%.*}";
提取名称。 Ref如果您希望单引号出现在 eval 中,请转义它们:\'
不要使用 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/