我有一个带有双破折号的文件名列表:
New York--1984 and counting.txt
Timeless Wonders--Silver-Guardians.txt
Project Blue Gale--Hills of Green.txt
我需要删除双破折号和双破折号之前的所有字符:
1984 and counting.txt
Silver-Guardians.txt
Hills of Green.txt
以下是使用SED的模式代码:
for f in *; do mv "$f" "$(sed 's/[^\--]*--//')"; done
RE错误:无效的字符范围
如果我更改它,那么它只会搜索一个破折号,它可以工作。那么如何搜索双破折号?提前致谢。
答案 0 :(得分:3)
这可能对您有用(GNU并行):
parallel --dryrun mv {} {= s/.*?--// =} ::: *.txt
在带有源文件的目录中运行命令并检查输出。如果所有都签出,请删除--dryrun
选项,然后再次运行。
使用GNU sed的替代解决方案:
ls *.txt | sed -E 'h;s/--/\n/;H;g;s/(.*)\n.*\n(.*)/mv -v "\1" "\2"/e'
如果要在实际运行前进行检查,请删除e
替换标志。
答案 1 :(得分:2)
该错误是由于您的[^\--]
模式在\
(第92页)和-
(第45号)之间定义了一个范围而造成的,这是错误的。 >
我建议使用
for f in *; do mv "$f" "$(sed 's/^[^-]*--//' <<< "$f")"; done
sed 's/^[^-]*--//'
命令将从字符串的开头到-
子字符串中除去除--
之外的所有0个或更多字符。
或者,您可以使用参数扩展${f#*--}
(与indicated by @tripleee一样)。它将从字符串开头(#*
)到第一个--
为止的尽可能少的0个或多个字符。
请参见online demo:
s="New York--1984 and counting.txt"
echo "${s#*--}";
sed 's/^[^-]*--//' <<< "$s"
输出:
1984 and counting.txt
1984 and counting.txt
答案 2 :(得分:1)
您可以使用rename
tool(Perl而不是util-linux)来实现:
$ rename -n 's/.*?--//' *.txt
'New York--1984 and counting.txt' would be renamed to '1984 and counting.txt'
'Project Blue Gale--Hills of Green.txt' would be renamed to 'Hills of Green.txt'
'Timeless Wonders--Silver-Guardians.txt' would be renamed to 'Silver-Guardians.txt'
删除-n
实际上会执行重命名。 .*?--
是一个正则表达式,用于非贪婪地匹配直到--
首次出现之前的所有内容。