我如何查找并替换每个出现的:
subdomainA.example.com
与...一起使用subdomainB.example.com
如何递归地在 /home/www/
目录树下的每个文本文件中进行操作?
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
-print0
参数告诉find
命令用空字符(而不是新行)分隔每个结果的输出。即使您的目录中有文件名包含换行符,这种设置也可以让xargs
命令在正确的文件名上工作。
\( -type d -name .git -prune \)
是一个表达式,它完全跳过了所有名为.git
的目录。如果您使用SVN或者有其他要保留的文件夹,只需匹配更多名称即可扩展它。 它与-not -path .git
大致等效,但更有效率,因为它直接跳过整个目录而不是检查其中的每个文件。 在它之后需要使用-o
参数,这是由于-prune
实际上的工作方式所导致的。man find
。subdomainA\.example\.com
值中点被转义了,而在第二个sudomainB.example.com
值中未被转义?我按建议的格式执行了它,似乎完美地完成了工作,但我很好奇为什么只针对第一个字符串模式进行转义。 - elrobisfind . -type f -print0 | xargs -0 sed -i -e 's/\r$//'
在特定目录中递归替换所有文件中的CRLF为LF。 - KaiserKatzefind . \( ! -regex '.*/\..*' \) -type f | LC_ALL=C xargs sed -i '' 's/foo/bar/g'
- Mushrankhan对于我来说最简单的方法是
grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'
.svn
文件夹,这种方法特别有效。例如:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
。 - phyattsed -i
命令会导致错误提示sed: 1: "file_path": invalid command code.
。这是因为在macOS上-i标志的含义与其他平台不同。可以使用grep -rl old . | xargs sed -i "" -e 's/old/new/g'
命令进行替换操作。这篇文章提供了相关帮助。 - Ben Butterworthgrep -Irl oldtext . | xargs sed -i 's/oldtext/newtext/g'
。这个命令可以搜索指定目录下的所有文件,把包含"oldtext"的文本替换成"newtext"。 - TomDanegrep -rl 'SEARCHSTRING' ./ | LC_ALL=C xargs sed -i'' 's/SEARCHSTRING/REPLACESTRING/g'
- Mushrankhangrep -rlZ oldtext . | xargs -0 sed -i 's/oldtext/newtext/g'
。参考链接:https://dev59.com/83PYa4cB1Zd3GeqPmbeu - toto_tico注意:不要在包含git仓库的文件夹上运行此命令,否则会破坏你的git索引。
find /home/www/ -type f -exec \
sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +
与其他回答相比,这个回答更简单,并且使用的是sed而不是perl,这正是原始问题所要求的。
-i
选项中显式提供空字符串参数。例如:
sed -i'' 's/original/replacement/g'
- Nathan Craikegrep -rl placeholder . | grep -Ev ".git" | xargs sed -i s/placeholder/lol/g
(grep -Ev 排除模式)。提示:在实际运行替换之前,先不要使用 -i
参数进行干运行。 - Eos Antigen所有的技巧都差不多,但我喜欢这一个:
find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} +
find <mydir>
:查找目录中的内容。
-type f
:
文件类型为:普通文件
-exec command {} +
:
此选项会在所选文件上运行指定命令,但命令行是通过将每个选择的文件名附加在末尾来构建的;该命令调用的总次数将远少于匹配的文件数。命令行的构建方式与xargs构建其命令行的方式非常相似。命令中只允许出现一个“{}”。命令在起始目录中执行。
对于我来说,最容易记住的解决方案是https://dev59.com/WXI95IYBdhLWcg3w3yFU#2113224,即:
sed -i '' -e 's/subdomainA/subdomainB/g' $(find /home/www/ -type f)
注意: -i ''
可解决OSX中的问题 sed: 1: "...": invalid command code .
注意: 如果要处理的文件过多,会出现 Argument list too long
的错误。解决方法是使用上面介绍的 find -exec
或者 xargs
。
sed: can't read : No such file or directory
的错误信息。为什么会出现这个问题,如何解决? - pmorcd /home/www && find . -type f -print0 |
xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'
对于使用银色搜索器(ag
)的任何人
ag SearchString -l0 | xargs -0 sed -i 's/SearchString/Replacement/g'
由于ag默认忽略git/hg/svn文件/文件夹,因此在仓库内运行是安全的。
这个适用于git仓库,并且更简单:
Linux:
git grep -z -l 'original_text' | xargs -0 sed -i 's/original_text/new_text/g'
Mac:
git grep -z -l 'original_text' | xargs -0 sed -i '' -e 's/original_text/new_text/g'
git-grep
的-z
选项和xargs -0
一起使用。 - gniourf_gniourfgit grep
明显只有在 git
存储库中才有意义。一般替代方法是 grep -r
。 - tripleee-z
参数,git-grep
将使用空字节而非换行符来分隔输出字段;使用-0
参数,xargs
将使用空字节而非空格来读取输入,并避免处理引号等字符时出现问题。因此,如果您不想在文件名中包含空格、引号或其他特殊字符时破坏命令,则应该使用以下命令:git grep -z -l 'original_text' | xargs -0 sed ...
。 - gniourf_gniourf如果您需要排除目录(--exclude-dir=..folder
),并且可能还有带空格的文件名(使用grep -Z
和xargs -0
中的0Byte来解决)的简单方法。
grep -rlZ oldtext . --exclude-dir=.folder | xargs -0 sed -i 's/oldtext/newtext/g'
sed
处理的文件数量,您可以使用 grep
来查找字符串实例:
为了缩小递归搜索的范围,您可以使用 grep
命令来查找包含指定字符串的文件:
grep -rl <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
如果你运行man grep
,你会注意到你也可以定义一个--exlude-dir="*.git"
标志,如果你想要省略搜索.git目录,避免像其他人礼貌地指出的那样遇到git索引问题。
带你到:
grep -rl --exclude-dir="*.git" <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g
-path ./.git -prune -o
在find . -path ./.git -prune -o -type f -name '*matchThisText*' -print0
中排除一个目录(例如git)的结果。 - devinbost