#!/usr/local/bin/bash -x
find * /home/www -type f | while read files
do
sedtest=$(sed -n '/^/,/$/p' "${files}" | sed -n '/subdomainA/p')
if [ "${sedtest}" ]
then
sed s'/subdomainA/subdomainB/'g "${files}" > "${files}".tmp
mv "${files}".tmp "${files}"
fi
done
1
要将文件减少到递归 sed ,你可以 grep 为你的字符串实例:
grep -rl <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
如果您运行 man grep ,您会注意到如果您想省略搜索.git目录,也可以定义 --exlude-dir="*.git" 标志,避免git索引问题,正如其他人礼貌地指出的那样 .
引导您:
grep -rl --exclude-dir="*.git" <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
PATH='your/path/here'
SEARCH=\'subdomainA.example.com\'
REPLACE=\'subdomainB.example.com\'
for file in $( find ${PATH} -P -type f ); do
TEMP_FILE=${file}.${RANDOM}.temp_file
if [ ! -e ${TEMP_FILE} ]; then
touch -C 819 ${TEMP_FILE}
sed -e 's/'$SEARCH'/'$REPLACE'/g' \
< ${file} > ${TEMP_FILE}
mv ${TEMP_FILE} ${file}
fi
done
注意事项:
解决方案排除错误处理
不是由OP标记的Bash
54
要替换git存储库中的所有实例,您可以使用:
git ls-files -z | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
有关列出存储库中所有文件的其他选项,请参阅List files in local git repo? . -z 选项告诉git用零字节分隔文件名,这确保 xargs (带选项 -0 )可以分隔文件名,即使它们包含空格或诸如此类的东西 .
30 回答
如果你想在不完全破坏你的SVN存储库的情况下使用它,你可以通过这样做来告诉'find'忽略所有隐藏文件:
我只是需要这个并且对可用示例的速度不满意 . 所以我想出了自己的:
Ack-grep在查找相关文件方面非常有效 . 这个命令轻而易举地取代了~14.5万个文件,而其他文件花费了很长时间,我不能等到它们完成 .
例如,'s a version that should be more general than most; it doesn' t需要
find
(使用du
代替) . 它确实需要xargs
,它只能在Plan 9的某些版本中找到(如9front) .如果要添加文件扩展名等过滤器,请使用
grep
:Note :不要在包含git repo的文件夹上运行此命令 - 更改为.git可能会损坏您的git索引 .
与此处的其他答案相比,这比大多数答案更简单,并使用sed而不是perl,这是原始问题所要求的 .
这个与git存储库兼容,有点简单:
Linux的:
苹果电脑:
(感谢http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/)
试试这个:
我只是使用上衣:
要将文件减少到递归
sed
,你可以grep
为你的字符串实例:如果您运行
man grep
,您会注意到如果您想省略搜索.git目录,也可以定义--exlude-dir="*.git"
标志,避免git索引问题,正如其他人礼貌地指出的那样 .引导您:
对我来说,最容易记住的解决方案是https://stackoverflow.com/a/2113224/565525,即:
NOTE :
-i ''
解决了OSX问题sed: 1: "...": invalid command code .
NOTE :如果要处理的文件太多,您将获得
Argument list too long
. 解决方法 - 使用上述的find -exec
或xargs
解决方案 .使用
grep
和sed
的组合您可以使用awk解决此问题,如下所示,
希望对你有帮助 !!!
一种更简单的方法是在命令行中使用以下内容
作为额外的一个漂亮的oneliner . 使用git grep .
对于任何使用silver searcher的人(
ag
)由于ag默认忽略git / hg / svn文件/文件夹,因此可以安全地在存储库中运行 .
Note :不要在包含git repo的文件夹上运行此命令 - 更改为.git可能会损坏您的git索引 .
来自
man find
:对我来说最简单的方法是
所有技巧几乎都一样,但我喜欢这个:
find <mydir>
:在目录中查找 .-type f
:-exec command {} +
:grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done
我猜大多数人都不知道他们可以将某些东西输入到“while read file”中,它避免了那些令人讨厌的-print0 args,同时在文件名中预先设置了空格 .
在sed之前进一步添加
echo
允许您在实际执行之前查看将更改的文件 .根据this博客文章:
如果您不介意将
vim
与grep
或find
工具一起使用,则可以在此链接中跟进用户Gert给出的答案 - > How to do a text replacement in a big folder hierarchy? .这是交易:
递归grep以查找要在特定路径中替换的字符串,并仅获取匹配文件的完整路径 . (那将是
$(grep 'string' 'pathname' -Rl)
.(可选)如果要在集中目录中对这些文件进行预备,也可以使用它:
cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'
之后,您可以按照类似于给定链接上提供的方案,在
vim
中随意编辑/替换::bufdo %s#string#replacement#gc | update
对于IBMi上的Qshell(qsh),不是由OP标记的bash .
qsh命令的局限性:
find没有-print0选项
xargs没有-0选项
sed没有-i选项
Thus the solution in qsh:
注意事项:
解决方案排除错误处理
不是由OP标记的Bash
要替换git存储库中的所有实例,您可以使用:
有关列出存储库中所有文件的其他选项,请参阅List files in local git repo? .
-z
选项告诉git用零字节分隔文件名,这确保xargs
(带选项-0
)可以分隔文件名,即使它们包含空格或诸如此类的东西 .更改多个文件(并将备份保存为
*.bak
):将获取目录中的所有文件并将
|
替换为名为“Perl pie”的x(简单的馅饼)这是我为OSX和Windows(msys2)找到的最佳解决方案 . 应该可以使用任何可以获得sed的gnu版本的东西 . 跳过.git目录,这样就不会破坏你的校验和 .
在mac上,首先安装coreutils并确保gsed在路径中 -
然后我把这个函数粘贴在我的zshrc / bashrc - >中
find /home/www/ -type f
将列出/ home / www /(及其子目录)中的所有文件 . "-exec"标志告诉find在找到的每个文件上运行以下命令 .是对文件运行的命令(一次多个) .
{}
被文件名替换 . 命令末尾的+
告诉find
为许多文件名构建一个命令 .根据
find
手册页:"The command line is built in much the same way that xargs builds its command lines."因此,可以在不使用
xargs -0
或-print0
的情况下实现目标(并处理包含空格的文件名) .A bit old school but this worked on OS X.
几乎没有技巧:
•仅编辑当前目录下扩展名为
.sls
的文件•必须对
.
进行转义以确保sed
不将它们评估为"any character"•
,
用作sed
分隔符,而不是通常的/
另请注意,这是编辑一个Jinja模板以在
import
的路径中传递variable
(但这是偏离主题的) .First, verify your sed command does what you want (this will only print the changes to stdout, it will not change the files):
Edit the sed command as needed, once you are ready to make changes:
注意 sed 命令中的
-i ''
,我不想创建原始文件的备份(如In-place edits with sed on OS X或本页中Robert Lujo的评论中所述) .快乐的人们!
只是为了避免改变
NearlysubdomainA.example.com
subdomainA.example.comp.other
但仍然
(也许在域根背后的想法不好)