Grep 具有特定下划线模式的文件名
Grep a filename with a specific underscore pattern
我正在尝试使用 egrep 和 regex 从文件中 grep 一个模式,但没有成功。
我需要的是获取一个文件,例如约定名称为:
xx_code_lastname_firstname_city.doc
代码应至少有 3 位数字,姓氏和名字以及城市可以根据尺码变化
我正在尝试下面的代码,但它无法实现我想要的:
ls -1 | grep -E "[xx_][A-Za-z]{3,}[_][A-Za-z]{2,}[_][A-Za-z]{2,}[_][A-Za-z]{2,}[.][doc|pdf]"
那是试图从开头得到标准的 xx_,然后是至少有 3 个单词的任何代码,之后它必须有另一个下划线,依此类推。
有人可以帮忙吗?
考虑一个extglob,如下:
#!/bin/bash
shopt -s extglob # turn on extended globbing syntax
files=( xx_[[:alpha:]][[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]]).@(doc|docx|pdf) )
[[ -e ${files[0]} ]] || -L ${files[0]} ]] && printf '%s\n' "${files[@]}"
之所以有效,是因为
[[:alpha:]][[:alpha:]]+([[:alpha:]])
...匹配任何包含三个或更多字母字符的字符串——其中两个显式,其中一个具有 +()
一个或多个 extglob 语法。
同样,
@(doc|docx|pdf)
...匹配这三个特定字符串中的任何一个。
所以您要匹配文字 xx_
?然后从那部分开始你的模式。
xx_
接下来是您要匹配的“3 位数字”。我将根据您自己的正则表达式假设 "digits" 是指字符(因此 [a-zA-Z]
字符 类)。让我们让量词成为非贪婪的,以避免任何无意的捕获行为。
xx_[a-zA-Z]{3,}?
对于名字和姓氏部分,我看到您指定了一个至少包含 2 个字符的可变长度。让我们通过在我们的量词后面附加 ?
字符来确保这些量词也是非贪婪的。根据您的正则表达式,您似乎也希望您的城市结构采用与名字和姓氏位相似的形式。让我们把这三个都加起来。
xx_[a-zA-Z]{3,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}\.
注意:我们不需要让 city 量词成为非贪婪的,因为我们断言它后面跟着一个文字 "."
,我们不希望它出现在文本中的其他任何地方'重新有兴趣匹配。请注意它是如何转义的,因为它是正则表达式语法中的元字符。
最后是文件扩展名,您的示例为 "docx"
。我还看到您在正则表达式中添加了 "doc"
和 "pdf"
扩展名。让我们把这三者结合起来。
xx_[a-zA-Z]{3,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}\.(docx?|pdf)
希望这能奏效。如果您需要任何说明,请发表评论。请注意 "doc"
和 "docx"
部分是如何压缩成一个元素的。这不是必需的,但我认为这种形式看起来更刻意。也可以写成(doc|docx|pdf)
。对我来说有点重复。
我正在尝试使用 egrep 和 regex 从文件中 grep 一个模式,但没有成功。
我需要的是获取一个文件,例如约定名称为:
xx_code_lastname_firstname_city.doc
代码应至少有 3 位数字,姓氏和名字以及城市可以根据尺码变化
我正在尝试下面的代码,但它无法实现我想要的:
ls -1 | grep -E "[xx_][A-Za-z]{3,}[_][A-Za-z]{2,}[_][A-Za-z]{2,}[_][A-Za-z]{2,}[.][doc|pdf]"
那是试图从开头得到标准的 xx_,然后是至少有 3 个单词的任何代码,之后它必须有另一个下划线,依此类推。 有人可以帮忙吗?
考虑一个extglob,如下:
#!/bin/bash
shopt -s extglob # turn on extended globbing syntax
files=( xx_[[:alpha:]][[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]])_[[:alpha:]]+([[:alpha:]]).@(doc|docx|pdf) )
[[ -e ${files[0]} ]] || -L ${files[0]} ]] && printf '%s\n' "${files[@]}"
之所以有效,是因为
[[:alpha:]][[:alpha:]]+([[:alpha:]])
...匹配任何包含三个或更多字母字符的字符串——其中两个显式,其中一个具有 +()
一个或多个 extglob 语法。
同样,
@(doc|docx|pdf)
...匹配这三个特定字符串中的任何一个。
所以您要匹配文字 xx_
?然后从那部分开始你的模式。
xx_
接下来是您要匹配的“3 位数字”。我将根据您自己的正则表达式假设 "digits" 是指字符(因此 [a-zA-Z]
字符 类)。让我们让量词成为非贪婪的,以避免任何无意的捕获行为。
xx_[a-zA-Z]{3,}?
对于名字和姓氏部分,我看到您指定了一个至少包含 2 个字符的可变长度。让我们通过在我们的量词后面附加 ?
字符来确保这些量词也是非贪婪的。根据您的正则表达式,您似乎也希望您的城市结构采用与名字和姓氏位相似的形式。让我们把这三个都加起来。
xx_[a-zA-Z]{3,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}\.
注意:我们不需要让 city 量词成为非贪婪的,因为我们断言它后面跟着一个文字 "."
,我们不希望它出现在文本中的其他任何地方'重新有兴趣匹配。请注意它是如何转义的,因为它是正则表达式语法中的元字符。
最后是文件扩展名,您的示例为 "docx"
。我还看到您在正则表达式中添加了 "doc"
和 "pdf"
扩展名。让我们把这三者结合起来。
xx_[a-zA-Z]{3,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}?_[a-zA-Z]{2,}\.(docx?|pdf)
希望这能奏效。如果您需要任何说明,请发表评论。请注意 "doc"
和 "docx"
部分是如何压缩成一个元素的。这不是必需的,但我认为这种形式看起来更刻意。也可以写成(doc|docx|pdf)
。对我来说有点重复。