Bash:按模式提取文件名并将其插入数组

Bash:按模式提取文件名并将其插入数组,bash,Bash,我有一个文件夹中的文件列表,我想用以下模式提取文件名并将它们插入数组 这种模式是,文件名总是以“MCABC_u”或“MCBBC_u”开头,然后是日期,然后以“.csv”结尾 例如,“MCABC_20110101.csv”、“MCBBC_20110304.csv” 现在,我只能提出下面的解决方案,但它并不理想 ls | grep-E“MCABC_U8;[A-Za-z0-9]*| MC221_U8;[A-Za-z0-9]*” 我读到使用ls是不好的。我应该使用glob 我对bash脚本完全不熟悉。如

我有一个文件夹中的文件列表,我想用以下模式提取文件名并将它们插入数组

这种模式是,文件名总是以“MCABC_u”或“MCBBC_u”开头,然后是日期,然后以“.csv”结尾

例如,“MCABC_20110101.csv”、“MCBBC_20110304.csv”

现在,我只能提出下面的解决方案,但它并不理想

ls | grep-E“MCABC_U8;[A-Za-z0-9]*| MC221_U8;[A-Za-z0-9]*”

我读到使用
ls
是不好的。我应该使用
glob

我对bash脚本完全不熟悉。如何用上面的模式提取文件名并将其插入数组中?谢谢

更新:感谢您的回答。非常感谢您的回答。我有以下代码

#!/bin/bash
shopt -s nullglob
files=(MC[1-2]21_All_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].csv)
echo ${#files[*]}
echo ${files[0]}
这是我运行
bash testing.sh
时得到的结果

:无效的shell选项名称:第2行:shopt:nullglob 1. (MC[1-2]21.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].csv)

但是,如果我只是在命令行
files=(MC[1-2]21_All[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].csv)
上运行,然后
echo${files[*]}
,我会设法获得输出:

MC121_All_20180301.csv MC121_All_20180302.csv MC121_All_20180305.csv MC221_All_20180301.csv MC221_All_20180302.csv MC221_All_20180305.csv

我很困惑。为什么会发生这种情况?(请注意,我是在10号窗口的ubuntu上运行的。)

我想你可以直接用glob填充数组:

files=( MC[AB]BC_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].csv )

“日期”部分当然可以改进,因为它匹配完全无效的日期,如98765432,但这可能不是问题。

这将在BASH中起作用

#!/bin/bash
for file_name in M*
do

    line="$line $( printf "${file_name%_*}")"
done
array=( $line )
echo "${array[2]}"
另一种方式:
问候!

考虑使用来进行文件搜索。是的。我确实尝试过使用find,即
find.-regextype sed-regex'MC121'
但它不返回任何内容。我对bash和regex非常陌生。我不太确定哪里出错了。我认为OP需要真实的文件名,而不是虚构的。对不起,我不明白你的意思。如果我的目录中有
MCABC_20110101.csv
MCBBC_20110304.csv
,这将创建一个包含这两个文件名的数组。我刚刚在命令行上测试了您的代码行,它成功了。但当我将同一行代码放在shell脚本中时,它失败了,
echo${files[*]}
返回1,而
echo${files[0]}
返回
(MC[AB]BC_uu0;[0-9][0-9][0-9][0-9][0-9][0-9].csv)
。我做错了什么?那是因为glob无法匹配任何文件,所以数组中只有一个元素:glob本身。您可以使用shell选项
shopt-s nullglob来防止这种情况发生(这将导致空数组)或
shopt-s failglob
(这将导致错误消息)但是我在命令行上测试了同一行代码,它成功地输出了我想要的文件名。只是当我将它放入bash脚本时,它失败了。我还添加了您提到的选项,它返回了
:无效的shell选项名称g:line 4:shopt:nullglob
我不明白您为什么要使用
printf
,但在变量之前应该始终使用格式说明符,例如
%s
。我不知道为什么要删除文件名中最后一个
之后的所有内容,我建议不要使用依赖于单词拆分的做法,如
数组=($line)
。请注意,如果要在循环中构建数组,可以使用
files\u array+=(“$file\u name”)
#!/bin/bash

declare -a files_array
i=0
for file_name in M*
do
    files_array[$i]="$( printf "${file_name%_*}")"
    (( i++ ))
done

echo "${files_array[2]}"