我正在尝试重命名我的应用程序中的许多文件,并且需要能够通过仅替换匹配文本的 git(即 git mv %filenamematch% %replacement%)在应用程序根目录中的所有子目录中进行重命名。不过,我不擅长编写 bash 脚本。
更新:如果也重命名匹配的目录就好了!
最佳答案
这应该可以解决问题:
for file in $(git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | uniq); do git mv $file $(echo $file | sed -e 's/%filenamematch%/%replacement%/'); done
要了解它的作用,您需要了解带有“|”的管道并使用“$(...)”进行命令替换。这些强大的 shell 构造允许我们组合多个命令来获得我们需要的结果。参见 Pipelines和 Command Substitution .
这是单行代码中发生的事情:
git ls-files
:这会生成 Git 存储库中的文件列表。它类似于您可以从ls
获得的内容,只是它只输出 Git 项目文件。从此列表开始可确保您的 .git/目录中的任何内容都不会被触及。| grep %filenamematch%
:我们从git ls-files
中获取列表并通过 grep 将其过滤为仅包含我们要查找的单词或模式的文件名。| sed -e 's/\(%filenamematch%[^/]*\).*/\1/'
:我们通过 sed 传递这些匹配项(流编辑器),执行 (-e) sed 的 s(替换)命令以在我们的匹配目录之后切掉任何/和后续字符(如果它恰好是一个)。| uniq
:在匹配目录的情况下,既然我们已经切掉了包含的目录和文件,那么可能会有很多匹配行。我们使用 uniq 将它们全部排成一行。for file in ...
: shell 的 "for" command将遍历列表中的所有项目(文件名)。每个文件名依次赋值给变量“$file”,然后执行分号(;)后的命令。sed -e 's/%filenamematch%/%replacement%/'
:我们使用 echo通过 sed 传递每个文件名,再次使用它的替换命令——这次是对文件名执行我们的模式替换。git mv
:我们使用此 git 命令将现有文件 ($file) mv 为新文件名(由 sed 更改的文件名)。
更好地理解这一点的一种方法是单独观察这些步骤中的每一个。为此,请在您的 shell 中运行以下命令,并观察输出。所有这些都是非破坏性的,只会生成供您观察的列表:
git ls-files
git ls-文件 | grep %文件名匹配%
git ls-文件 | grep %文件名匹配% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/'
git ls-文件 | grep %文件名匹配% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' |唯一性
$(git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | 中的文件唯一性);做 echo $file
;完成$(git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | 中的文件唯一性);做 echo $file | sed -e 's/%filenamematch%/%replacement%/'
;完成
关于git 重命名许多文件和文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9984722/