如何通过正则表达式重命名批量文件?
How to rename bulk files by regex?
我有一堆文件从 wget 操作中吐出。很多都有这样的文件名:
bootstrap.min.css?v=30cad4497c.css
font-awesome.min.css?v=30cad4497c.css
screen.css?v=30cad4497c.css
是的,这些是文件名、问号和等号等等。
?v=30cad4497.css
东西出现的原因我知道。如何重命名所有文件以删除“?”之后的所有内容角色?
我很乐意为此编写几行 shell 脚本,但我不想不得不搞砸 python/node/ruby/whatever。
在bash中:
for file in *[?]* ; do mv $file ${file%%[?]*} ; done
*[?]*
表示匹配文件名中包含问号的文件。 ${file%%glob}
表示在字符串的末尾 剥离所有匹配glob 的文本。 ${file##glob}
表示去掉字符串开头所有与 glob 匹配的文本。请注意,这些是 文件 glob,而不是正则表达式。文件 glob 是我们经常用来匹配 bash.
中的文件
works well with the specific filenames at hand, but, for general robustness, the variable references should be double-quoted to ensure that they're used as-is (to protect their values from shell expansions):
for file in *\?* ; do mv "$file" "${file%%\?*}"; done
还要注意我是如何使用 \?
来匹配 literal ?
的,因为它是意图的更直接表达 - 尽管使用字符 set 仅包含一个元素 ([?]
) 也可以。
关于 Pattern Matching Notation 使用的注释:
正如 Danny 指出的那样,模式虽然关系很远,但 不是 正则表达式(正则表达式),上面的 link 到 POSIX规范描述了它们的具体语法。
模式不只有在pathname expansion (globbing), but also in parameter expansion中使用,其中${file%%\?*}
是一个例子:
%%
- 与 %
相反 - 从 $file
的值中去除 最长的 后缀,匹配 后面的模式。
- 至少对于仅包含单个
?
的示例输入,通过 %
剥离 最短 后缀也可以(${file%\?*}
).
请注意,在参数扩展中使用模式,例如 %%
独立于 路径名扩展(通配) ,如以下示例所示:
$ foo='bar'; echo "${foo%a*}"
b # suffix 'a' followed by any chars. stripped
此外,在Bash(以及Ksh和Zsh)中,您还可以在==
运算符的RHS上使用模式(注意这是不是 POSIX 标准的一部分):
$ [[ foo == 'f'* ]] && echo YES
YES
请注意 *
等模式元字符必须 不加引号 才能被识别(regex-matching operator, =~
也是如此)。
我有一堆文件从 wget 操作中吐出。很多都有这样的文件名:
bootstrap.min.css?v=30cad4497c.css
font-awesome.min.css?v=30cad4497c.css
screen.css?v=30cad4497c.css
是的,这些是文件名、问号和等号等等。
?v=30cad4497.css
东西出现的原因我知道。如何重命名所有文件以删除“?”之后的所有内容角色?
我很乐意为此编写几行 shell 脚本,但我不想不得不搞砸 python/node/ruby/whatever。
在bash中:
for file in *[?]* ; do mv $file ${file%%[?]*} ; done
*[?]*
表示匹配文件名中包含问号的文件。 ${file%%glob}
表示在字符串的末尾 剥离所有匹配glob 的文本。 ${file##glob}
表示去掉字符串开头所有与 glob 匹配的文本。请注意,这些是 文件 glob,而不是正则表达式。文件 glob 是我们经常用来匹配 bash.
for file in *\?* ; do mv "$file" "${file%%\?*}"; done
还要注意我是如何使用 \?
来匹配 literal ?
的,因为它是意图的更直接表达 - 尽管使用字符 set 仅包含一个元素 ([?]
) 也可以。
关于 Pattern Matching Notation 使用的注释:
正如 Danny 指出的那样,模式虽然关系很远,但 不是 正则表达式(正则表达式),上面的 link 到 POSIX规范描述了它们的具体语法。
模式不只有在pathname expansion (globbing), but also in parameter expansion中使用,其中
${file%%\?*}
是一个例子:%%
- 与%
相反 - 从$file
的值中去除 最长的 后缀,匹配 后面的模式。- 至少对于仅包含单个
?
的示例输入,通过%
剥离 最短 后缀也可以(${file%\?*}
).
请注意,在参数扩展中使用模式,例如 %%
独立于 路径名扩展(通配) ,如以下示例所示:
$ foo='bar'; echo "${foo%a*}"
b # suffix 'a' followed by any chars. stripped
此外,在Bash(以及Ksh和Zsh)中,您还可以在==
运算符的RHS上使用模式(注意这是不是 POSIX 标准的一部分):
$ [[ foo == 'f'* ]] && echo YES
YES
请注意 *
等模式元字符必须 不加引号 才能被识别(regex-matching operator, =~
也是如此)。