循环遍历具有特定扩展名的文件(并非所有扩展名都可能存在)

循环遍历具有特定扩展名的文件(并非所有扩展名都可能存在)

我有以下简单的脚本来循环遍历具有特定扩展名的文件,并生成一个带有解析的文件名(不带扩展名)的 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 允许不匹配任何文件的模式(请参阅上面的路径名扩展)扩展为空字符串,而不是它们本身。

例如,比较nullglobset和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.

相关内容