Linux 和 macOS 單次及批次修改檔案名稱 mv, rename

Posted in :

在 macOS 電腦裡突然發生有一個檔案名稱錯掉了,原本是 head_pard 我想修改成 head_part,如果是使用 windwos 平台,使用:

rename head_pard* head_part*

指令就解決了。但在 Linux 和 macOS 裡的 mv 指令,無法處理批次換名字的工作。解法是另外一個外部指令。

在 macOS 裡,rename 需要使用下面的指令來安裝:

brew install rename

在 mac OSX 裡最後服用的指令是:

rename -s head_pard head_part head_pard*

在 linux 裡,可以少掉一個 -s 的參數:

rename head_pard head_part head_pard*

不使用 rename 外部指令,也可以使用 find 指令來完成:

find . -type f -name 'Lucky-*' | while read FILE ; do
     newfile="$(echo ${FILE} |sed -e 's/pard/part/')" ;
     mv "${FILE}" "${newfile}" ;

感覺上,使用 rename 指令會簡單點。

Mac OSX rename 指令用法:

    rename [switches|transforms] [files]


    --man (read the full manual)
    -0/--null (when reading from STDIN)
    -f/--force or -i/--interactive (proceed or prompt when overwriting)
    -g/--glob (expand "*" etc. in filenames, useful in Windows™ CMD.EXE)
    -l/--symlink or -L/--hardlink

    Transforms, applied sequentially:

    -s/--subst *from* *to*
    -S/--subst-all *from* *to*
    --camelcase --urlesc --nows --rews --noctrl --nometa --trim (see manual)

Mac OSX reanme使用範例:

For example, to strip the extension from all ".bak" files, you might
use either of these command lines:

rename -x *.bak

rename 's/\.bak\z//' *

These do not achive their results in exactly the same way: the former
only takes the files that match "*.bak" in the first place, then strips
their last extension; the latter takes all files and strips a ".bak"
from the end of those filenames that have it. As another alternative,
if you are confident that none of the filenames has ".bak" anywhere
else than at the end, you might instead choose to write the latter
approach using the "-s" switch:

rename -s .bak '' *

Of course you can do multiple changes in one go:

rename -s .tgz .tar.gz -s .tbz2 .tar.bz2 *.t?z*

But note that transforms are order sensitive. The following will not do
what you probably meant:

rename -s foo bar -s bar baz *

Because rules are cumulative, this would first substitute foo with bar;
in the resulting filenames, it would then substitute bar with baz. So

in most cases, it would end up substituting foo with baz X probably not
your intention. So you need to consider the order of rules.

If you are unsure that your modification rules will do the right thing,
try doing a verbose dry run to check what its results would be. A dry
run is requested by passing "-n":

rename -n -s bar baz -s foo bar *

You can combine the various transforms to suit your needs. E.g. files
from MicrosoftX WindowsX systems often have blanks and (sometimes
nothing but) capital letters in their names. Let's say you have a heap
of such files to clean up, and you also want to move them to
subdirectories based on extension. The following command will do this
for you:

rename -p -c -z -X -e '$_ = "$EXT/$_" if @EXT' *

Here, "-p" tells rename to create directories if necessary; "-c" tells
it to lower-case the filename; "-X" remembers the file extension in the
$EXT and @EXT variables; and finally, the "-e" expression uses those to
prepend the extension to the filename as a directory, if there is one.


發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *