Jon*_*sch 30
这应该做的伎俩:
for file in $(git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | uniq); git mv $file $(echo $file | sed -e 's/%filenamematch%/%replacement%/')
Run Code Online (Sandbox Code Playgroud)
要了解这是做什么的,你需要用"|"来理解管道 并用"$(...)"替换命令.这些强大的shell结构允许我们组合几个命令来获得我们需要的结果.请参阅管道和命令替换.
以下是这个单行中发生的事情:
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"命令将遍历列表中的所有项(文件名).依次为每个文件名,它分配给变量"$ file",然后在分号(;)之后执行命令.
sed -e 's/%filenamematch%/%replacement%/':我们使用echo通过sed管道每个文件名,再次使用它的替换命令 - 这次在文件名上执行我们的模式替换.
git mv:我们使用这个git命令将现有文件($ file)转换为新文件名(由sed更改的文件名).
更好地理解这一点的一种方法是单独观察这些步骤.为此,请在shell中运行以下命令,并观察输出.所有这些都是非破坏性的,只为您的观察产生列表:
git ls-files
git ls-files | grep %filenamematch%
git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/'
git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | uniq
for file in $(git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | uniq); echo $file
for file in $(git ls-files | grep %filenamematch% | sed -e 's/\(%filenamematch%[^/]*\).*/\1/' | uniq); echo $file | sed -e 's/%filenamematch%/%replacement%/'
GoZ*_*ner 14
迟到了,但是,这应该在BASH中工作(对于文件和目录,但我对目录要小心):
find . -name '*foo*' -exec bash -c 'file={}; git mv $file ${file/foo/bar}' \;
Run Code Online (Sandbox Code Playgroud)
Fli*_*imm 14
使用以下命令使用正则表达式重命名文件rename:
rename 's/old/new/' *
Run Code Online (Sandbox Code Playgroud)
然后通过添加新文件并删除旧文件,使用Git注册更改:
git add .
git ls-files -z --deleted | xargs -0 git rm
Run Code Online (Sandbox Code Playgroud)
在较新版本的Git中,您可以使用该--all标志:
git add --all .
Run Code Online (Sandbox Code Playgroud)
git mv 在shell循环中?
(假设你在一个有合理外壳的平台上!)
建立在@ jonathan-camenish上:#(有人可以将其编辑成真正的链接吗?)
# things between backticks are 'subshell' commands. I like the $() spelling over ``
# git ls-files -> lists the files tracked by git, one per line
# | grep somestring -> pipes (i.e., "|") that list through a filter
# '|' connects the output of one command to the input of the next
# leading to: for file in some_filtered_list
# git mv f1 f2 -> renames the file, and informs git of the move.
# here 'f2' is constructed as the result of a subshell command
# based on the sed command you listed earlier.
for file in `git ls-files | grep filenamematch`; do git mv $file `echo $file | sed -e 's/%filenamematch%/%replacement%/'`; done
Run Code Online (Sandbox Code Playgroud)
这是一个较长的例子(在bash或类似的)
mkdir blah; cd blah;
touch old_{f1,f2,f3,f4} same_{f1,f2,f3}
git init && git add old_* same_* && git commit -m "first commit"
for file in $(git ls-files | grep old); do git mv $file $(echo $file | sed -e 's/old/new/'); done
git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: old_f1 -> new_f1
# renamed: old_f2 -> new_f2
# renamed: old_f3 -> new_f3
# renamed: old_f4 -> new_f4
#
Run Code Online (Sandbox Code Playgroud)
请参阅:http://en.wikibooks.org/wiki/Ad_Hoc_Data_Analysis_From_The_Unix_Command_Line/
| 归档时间: |
|
| 查看次数: |
12753 次 |
| 最近记录: |