我有以下简单的脚本来循环遍历具有特定扩展名的文件,并生成一个带有解析的文件名(不带扩展名)的 XML 文件。但是,如果目录中不存在任何扩展名,则会生成 *.ext 并弄乱结果。如何确保它只获取真实文件的名称而不是 *.wlens 之类的名称?
PS 我正在执行更复杂的名称解析(sed),因为文件可能包含“.”在名字里。如果有更有效的方法来做到这一点,我将不胜感激您的意见。
#!/bin/bash
echo "
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
" > retrieve_xmd_build_package.xml
for i in *.{wdash,wcomp,wlens};
do
echo "<members>" >> retrieve_xmd_build_package.xml
echo " " "$i"| sed 's#^\(.*\)\.\(.*\)#\1#' >> retrieve_xmd_build_package.xml
echo "</members>" >> retrieve_xmd_build_package.xml
done
echo "<name>WaveXMD</name>" >> retrieve_xmd_build_package.xml
echo "
</types>
<version>56.0</version>
</Package>
" >> retrieve_xmd_build_package.xml
以下是其中一个扩展名输入错误的结果:
<?xml version=1.0 encoding=UTF-8?>
<Package xmlns=http://soap.sforce.com/2006/04/metadata>
<types>
<members>
weekday DASH
</members>
<members>
*
</members>
<members>
weekday LENS 2
</members>
<members>
weekday LENS
</members>
<name>WaveXMD</name>
</types>
<version>56.0</version>
</Package>
答案1
就我个人而言,我倾向于使用find
,但您可以通过设置选项在 bash 中执行此nullglob
操作。即在循环之前的某处for
添加:
shopt -s nullglob
从man bash
:
nullglob
如果设置,bash 允许不匹配任何文件的模式(请参阅上面的路径名扩展)扩展为空字符串,而不是它们本身。
例如,比较nullglob
set和unset的差异。首先,取消设置(通常是默认设置,除非您在 .bashrc 或其他配置文件脚本中设置它):
$ shopt -u nullglob
$ for i in *.{wdash,wcomp,wlens}; do echo "$i"; done
*.wdash
*.wcomp
*.wlens
当前目录中不存在这些文件 glob,因此在nullglob
未设置的情况下,bash 将不匹配的 glob 扩展为自身(即仅使用 glob 作为文字字符串)
接下来设置 nullglob:
$ shopt -s nullglob
$ for i in *.{wdash,wcomp,wlens}; do echo "$i"; done
即 for 循环不会打印任何内容,因为 nullglob 设置会阻止不匹配的 glob 扩展到自身。
请注意,在 bash 中,该failglob
选项优先于nullglob
.所以如果failglob
设置了,nullglob
则没有效果。如果failglob
可能已设置,您需要使用 取消设置shopt -u failglob
才能使用nullglob
.