如何在外壳中使用正则表达式匹配文件名?

时间:2019-04-02 21:45:16

标签: linux shell

现在我有两个文件夹:

文件夹_1包含3个文件:a_v1.txt,b_v1.txt,c_v1.txt。

文件夹_2还包含3个文件:a_v2.txt,b_v2.txt,c_v2.txt。

我正在尝试使用正则表达式来匹配在v1和v2前面具有相同字符串的文件(例如{a_v1.txt,a_v2.txt})。我已经通过使用"^(.+?)v1", "^(.+?)v2"在Python中成功实现了这一点,但是我只是开始学习Shell而仍然不熟悉它。有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

在这种情况下,您可能根本不使用正则表达式,而是匹配一个目录中的文件名,然后构造要从另一目录中提取的文件名:

for name1 in Folder_1/*_v1.txt; do
    name2="Folder_2/$(basename "$name1" _v1.txt)_v2.txt"

    if [ -f "$name2" ]; then
        printf 'Have "%s" and "%s"\n' "$name1" "$name2"
    else
        printf 'Missing "%s"\n' "$name2"
    fi
done

这会循环遍历第一个目录中与*_v1.txt匹配的文件的路径名,并为每个路径名构造对应于我们期望在另一个目录中找到的文件的路径名。这是通过使用basename实用程序来完成的,该实用程序返回路径名的文件名部分,并删除了可选的后缀。

我们在此实用程序的输出之前添加并附加适当的字符串,然后进行测试以查看新路径名是否对应于常规文件(或指向一个文件的符号链接)。

您想对发现的文件对做些什么,您可以在if语句的第一个分支中执行此操作,或者在循环等效形式的if语句之后执行操作:

for name1 in Folder_1/*_v1.txt; do
    name2="Folder_2/$(basename "$name1" _v1.txt)_v2.txt"

    if [ ! -f "$name2" ]; then
        printf 'Missing "%s"\n' "$name2"
        continue
    fi

    printf 'Have "%s" and "%s"\n' "$name1" "$name2"
done

测试:

$ tree
.
|-- Folder_1
|   |-- a_v1.txt
|   |-- b_v1.txt
|   |-- c_v1.txt
|   `-- d_v1.txt
`-- Folder_2
    |-- a_v2.txt
    |-- b_v2.txt
    `-- c_v2.txt

2 directories, 7 files

循环的输出:

Have "Folder_1/a_v1.txt" and "Folder_2/a_v2.txt"
Have "Folder_1/b_v1.txt" and "Folder_2/b_v2.txt"
Have "Folder_1/c_v1.txt" and "Folder_2/c_v2.txt"
Missing "Folder_2/d_v2.txt"