在一个目录中有多个以fgh开头的文件,例如:

fghfilea
fghfileb
fghfilec

我想将它们全部重命名为以前缀jkl开头。是否有一个单独的命令来执行该操作,而不是逐个重命名每个文件?


当前回答

rename fgh jkl fgh*

其他回答

使用StringSolver工具(windows & Linux bash),通过示例处理:

filter fghfilea ok fghreport ok notfghfile notok; mv --all --filter fghfilea jklfilea

它首先根据示例计算一个过滤器,其中输入是文件名和输出(ok和notok,任意字符串)。如果filter有选项——auto或者在这个命令之后单独被调用,它会创建一个文件夹ok和一个文件夹notok,并分别将文件推送到它们。

然后使用过滤器,mv命令是一个半自动的移动,使用修饰符——auto变成自动的。使用前面的过滤器——filter,它找到了从fghfilea到jklfilea的映射,然后将其应用于所有过滤过的文件。


其他单行解决方案

做同样事情的其他等效方法(每一行都是等效的),所以你可以选择你最喜欢的方法。

filter fghfilea ok fghreport ok notfghfile notok; mv --filter fghfilea jklfilea; mv
filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter fghfilea "mv fghfilea jklfilea"
# Even better, automatically infers the file name
filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter "mv fghfilea jklfilea"

多步骤的解决方案

要仔细查看命令是否执行良好,您可以键入以下命令:

filter fghfilea ok
filter fghfileb ok
filter fghfileb notok

当你确信过滤效果不错时,执行第一步:

mv fghfilea jklfilea

如果你想测试,并使用前面的筛选器,输入:

mv --test --filter

如果转换不是你想要的(例如,即使用mv——解释你看到的东西是错误的),你可以输入mv——clear重新启动移动文件,或添加更多的例子mv input1 input2,其中input1和input2是其他例子

当你有信心的时候,就打字

mv --filter

瞧!所有重命名都是使用筛选器完成的。

免责声明:我是这篇论文的合著者。可能很快还会有bash生成功能。

(在我的Mac上)用Ruby做这个要容易得多。下面是两个例子:

# for your fgh example. renames all files from "fgh..." to "jkl..."
files = Dir['fgh*']

files.each do |f|
  f2 = f.gsub('fgh', 'jkl')
  system("mv #{f} #{f2}")
end

# renames all files in directory from "021roman.rb" to "021_roman.rb"
files = Dir['*rb'].select {|f| f =~ /^[0-9]{3}[a-zA-Z]+/}

files.each do |f|
  f1 = f.clone
  f2 = f.insert(3, '_')
  system("mv #{f1} #{f2}")
end

这是find + sed + xargs解决方案的扩展版本。

原来的解是这个和这个。

要求:搜索,修剪,正则表达式,重命名

我想重命名多个文件夹中的多个文件。 一些文件夹应该被删除。 我在cygwin上,不能让perl重命名工作,这是最流行的解决方案所需要的(我假设它很慢,因为它似乎没有修剪选项?)

解决方案

使用find可以有效地获取文件(带有修剪),并提供许多自定义选项。 使用sed替换正则表达式。 使用xargs将结果汇集到最终命令中。

例1:重命名*.js文件,忽略node_modules

这个示例查找文件并对找到的文件和重命名的文件进行回显。出于安全考虑,它目前没有移动任何东西。你需要用mv代替echo。

set -x # stop on error
set -e # verbose mode (echo all commands)

find "." -type f -not \( -path "**/node_modules/**" -prune \) -name "*.js" | 
  sed -nE "s/(.*)\/my(.*)/& \1\/YOUR\2/p" |
  xargs -n 2 echo  # echo first (replace with `mv` later)

上面的脚本转换为:

./x/y/my-abc.js

到这个:

./x/y/YOUR-abc.js

溶液分解

find "." -type f -not \( -path "**/node_modules/**" -prune \) -name "*.js" Searches for files (-type f). The -not part excludes (and, importantly does not traverse!) the (notoriously ginormous) node_modules folder. File name must match "*.js". You can add more include and exclude clauses. Refs: This post discusses recursive file finding alternatives. This post discusses aspects of pruning and excluding. man find sed -nE "s/(.*)\/my\-(.*\.js)/& \1\/YOUR-\2/p" NOTE: sed always takes some getting used to. -E enables "extended" (i.e. more modern) regex syntax. -n is used in combination with the trailing /p flag: -n hides all results, while /p will print only matching results. This way, we only see/move files that need changing, and ignore all others. Replacement regex with sed (and other regex tools) is always of the format: s/regex/replacement/FLAGS In replacement, the & represents the matched input string. This will be the first argument to mv. Refs: linux regex tutorial man sed xargs -n 2 echo Run the command echo with (the first two strings of) the replaced string. Refs: man xargs

好运!

使用find, xargs和sed:

find . -name "fgh*" -type f -print0 | xargs -0 -I {} sh -c 'mv "{}" "$(dirname "{}")/`echo $(basename "{}") | sed 's/^fgh/jkl/g'`"'

它比@nik的解决方案更复杂,但它允许递归地重命名文件。例如,结构,

.
├── fghdir
│   ├── fdhfilea
│   └── fghfilea
├── fghfile\ e
├── fghfilea
├── fghfileb
├── fghfilec
└── other
    ├── fghfile\ e
    ├── fghfilea
    ├── fghfileb
    └── fghfilec

会变成这样,

.
├── fghdir
│   ├── fdhfilea
│   └── jklfilea
├── jklfile\ e
├── jklfilea
├── jklfileb
├── jklfilec
└── other
    ├── jklfile\ e
    ├── jklfilea
    ├── jklfileb
    └── jklfilec

使它与xargs一起工作的关键是从xargs调用shell。

您也可以使用下面的脚本。它很容易在终端上运行…

//一次重命名多个文件

for file in  FILE_NAME*
do
    mv -i "${file}" "${file/FILE_NAME/RENAMED_FILE_NAME}"
done

例子:-

for file in  hello*
do
    mv -i "${file}" "${file/hello/JAISHREE}"
done