'对于 * 中的 f;做CP "$f" "$f" _copy;完成"不起作用,因为"foo.png_copy".如何解决?



在Linux上,命令:

for f in *; do cp "$f" "$f"_copy; done

不像预期的那样工作,因为"_copy"字符串被附加在文件扩展名之后,变成foo.png_copy而不是foo_copy.png。我怎么修理它?我能把绳子切开吗?

for f in *; do
    prefix="${f%.*}"
    suffix="${f:${#prefix}}"
    cp "$f" "${prefix}_copy${suffix}"
done

通过修剪匹配".*"的后缀来查找文件名的前缀。注意,如果文件名没有扩展名,这将是整个文件名;如果它有多个句号,它将只删除最后一个(例如,对于一个名为"this.that.etc.png"的文件,它将被修剪为"this.that.etc")。然后,它通过基于前缀的长度对文件名进行切片来查找后缀(${#prefix});无论是否删除任何内容,这都能正常工作。

警告:这将处理任何带有句点的文件名具有扩展名。例如,"file_v1.0"将被复制到"file_v1_copy.0"。

注意:如果你愿意,你可以跳过定义$后缀,而只是在复制命令中使用${f:${#prefix}} inline,但我认为这样更清楚。

使用basename,传递第二个参数:

for f in *; do
    cp "$f" "$(basename "$f" .png)_copy.png"
done

根据basename(1):

<标题>简介

basename string [suffix]

<标题>

basename实用程序删除[& help;]一个后缀,如果给定的话。

如果文件名只有句号

rename ".png" "_copy.png"  *.png

man rename

最新更新