如何在linux命令行中replace多个文件中的string

我需要replace文件夹中的许多文件中的string,只有ssh访问服务器。 我怎样才能做到这一点?

 cd /path/to/your/folder sed -i 's/foo/bar/g' * 

“foo”的发生将被replace为“bar”。

类似于Kaspar的答案,但用g标志来replace一行中的所有事件。

 find ./ -type f -exec sed -i 's/string1/string2/g' {} \; 

对于全局不区分大小写:

 find ./ -type f -exec sed -i 's/string1/string2/gI' {} \; 

@ kev的答案是好的,但只影响直接目录中的文件。下面的例子使用greprecursion查找文件。 它每次都适合我

 grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @ 

这对我工作:

 find ./ -type f -exec sed -i 's/string1/string2/' {} \; 

Howerver,这没有: sed -i 's/string1/string2/g' * 。 也许“富”不是为了string1和“酒吧”不是string2。

要replace多个文件中的string,您可以使用:

 grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g' 

例如

 grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g' 

来源博客

有一些标准答案已经列出。 通常,您可以使用findrecursion列出文件,然后使用sedperl执行操作。

对于大多数快速使用,您可能会发现命令rpl更容易记住。 这里是replace(富 – >酒吧),recursion的所有文件:

rpl -R foo bar .

你可能需要安装它( apt-get install rpl或类似的)。

但是,对于涉及正则expression式和后置replace,文件重命名以及searchreplace的更复杂的工作 ,我所知道的最通用和最强大的工具是repren ,一个我为某些人编写的小Python脚本更棘手的重命名和重构任务。 你可能更喜欢它的原因是:

  • 支持重命名文件以及search和replace文件内容。
  • 在承诺执行search和replace之前查看更改。
  • 支持正则expression式replace,全字,不区分大小写,保留大小写(replacefoo – > bar,Foo – > Bar,FOO – > BAR)模式。
  • 可以使用多个replace,包括掉换(foo – > bar和bar – > foo)或一组非唯一replace(foo – > bar,f – > x)。

要使用它, pip install repren 。 检查自述文件的例子。

要replace文件中的path(避免转义字符),可以使用以下命令:

 sed -i 's@old_path@new_path@g' 

@符号表示所有的特殊字符都应该在下面的string中被忽略。

如果您有可以使用的文件列表

 replace "old_string" "new_string" -- file_name1 file_name2 file_name3 

在我发现这个问题之前,我做了自己的解决scheme(和答案)。 我search了“replace”“几个”和“xml”的不同组合,因为这是我的应用程序,但没有find这个特定的组合。

我的问题:我有春季XML文件与testing用例的数据,包含复杂的对象。 java源代码的重构改变了很多类,并不适用于xml数据文件。 为了保存testing用例数据,我需要更改所有xml文件中的所有类名,分布在多个目录中。 所有的同时保存原始xml文件的备份副本(尽pipe这不是必须的,因为版本控制可以将我保存在这里)。

我正在寻找find + sed一些组合,因为它在其他情况下适用于我,但不能同时进行多个replace。

然后我发现问ubuntu的响应 ,它帮助我build立我的命令行:

 find -name "*.xml" -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \; 

它的工作完美(好吧,我的情况有六个不同的替代品)。 但请注意,它会触及当前目录下的所有* .xml文件。 因此,如果你对版本控制系统负责,你可能需要首先进行筛选,然后只传递给那些实际上有你想要的string的sed ; 喜欢:

 find -name "*.xml" -exec grep -e "firstWord" -e "secondWord" -e "thirdWord" {} \; -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \; 
 grep --include={*.php,*.html} -rnl './' -e "old" | xargs -i@ sed -i 's/old/new/g' @ 

脚本为multiedit命令

 multiedit [-n PATTERN] OLDSTRING NEWSTRING 

从Kaspar的答案,我做了一个bash脚本接受命令行参数,并可选地限制匹配模式的文件名。 保存在你的$ PATH中,然后生成可执行文件,然后使用上面的命令。

这是脚本:

 #!/bin/bash _help="\n Replace OLDSTRING with NEWSTRING recursively starting from current directory\n multiedit [-n PATTERN] OLDSTRING NEWSTRING\n [-n PATTERN] option limits to filenames matching PATTERN\n Note: backslash escape special characters\n Note: enclose STRINGS with spaces in double quotes\n Example to limit the edit to python files:\n multiedit -n \*.py \"OLD STRING\" NEWSTRING\n" # ensure correct number of arguments, otherwise display help... if [ $# -lt 2 ] || [ $# -gt 4 ]; then echo -e $_help ; exit ; fi if [ $1 == "-n" ]; then # if -n option is given: # replace OLDSTRING with NEWSTRING recursively in files matching PATTERN find ./ -type f -name "$2" -exec sed -i "s/$3/$4/g" {} \; else # replace OLDSTRING with NEWSTRING recursively in all files find ./ -type f -exec sed -i "s/$1/$2/" {} \; fi 

“你也可以使用find和sed,但是我发现这个perl的这一行很好地工作。

 perl -pi -w -e 's/search/replace/g;' *.php 
  • -e表示执行下面的代码行。
  • -i表示就地编辑
  • -w写警告
  • -p循环

“(摘自http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php

我最好的结果来自使用perl和grep(以确保文件具有searchexpression式)

 perl -pi -w -e 's/search/replace/g;' $( grep -rl 'search' ) 

如果文件包含反斜杠(通常是path),可以尝试如下所示:

 sed -i -- 's,<path1>,<path2>,g' * 

例如:

 sed -i -- 's,/foo/bar,/new/foo/bar,g' *.sh (in all shell scripts available) 

“foo”的第一行将被replace为“bar”。 你可以使用第二行来检查。

 grep -rl 'foo' . | xargs sed -i 's/foo/bar/g' grep 'foo' -r * | awk -F: {'print $1'} | sort -n | uniq -c 

你可以看到我写这篇文章: http : //jiasir.io/Replace-strings-with-sed-in-directory-and-sub-directories/

真的很蹩脚,但是我不能让任何sed命令在OSX上正常工作,所以我做了这个愚蠢的事情:

 :%s/foo/bar/g :wn 

^ – 复制这三行到我的剪贴板(是的,包括结束换行符),然后:

vi *

并按住command-v直到它说没有剩下的文件。

阿呆… …哈克有效…

当使用-i开关调用stream编辑器时,stream编辑器会修改多个“inplace”文件,这会使备份文件以参数结尾。 所以

 sed -i.bak 's/foo/bar/g' * 

在此文件夹中的所有文件中用barreplacefoo ,但不下降到子文件夹中。 这将为您的目录中的每个文件生成一个新的.bak文件。 要recursion执行此目录及其所有子目录中的所有文件,需要使用助手(如find )来遍历目录树。

 find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' * 

find可以通过指定更多的参数,如find ./ -name '*.php' -or -name '*.html' -print0 ,进一步限制要修改的文件。


注意:GNU sed不需要文件结尾, sed -i 's/foo/bar/g' *也能工作。 FreeBSD的sed需要一个扩展名,但是允许两者之间有空格,所以sed -i .bak s/foo/bar/g *可以工作。

可以使用下面的命令首先search文件并replace文件

找 。 | xargs grepsearchstring| sed's /searchstring/新string/ g'

如find。 | xargs grep abc | sed's / abc / xyz / g'

为了维护我的个人英语节点,我编写了一个实用程序脚本,用于recursion地replace目录下的所有文件,以replace多对旧/新string。

多对旧/新string在哈希映射中进行pipe理。

dir可以通过命令行或环境variables来设置,映射在脚本中是硬编码的,但是如果需要的话,你可以修改从文件加载的代码。

它需要bash 4.2,由于一些新的function。

en_standardize.sh:

 #! /bin/bash # (need bash 4.2+,) # # Standardize phonetic symbol of English. # # format: # en_standardize.sh [<dir>] # # params: # * dir # target dir, optional, # if not specified then use environment variable "$node_dir_en", # if both not provided, then will not execute, # * # paramCount=$# # figure target dir, if [ $paramCount -ge 1 ]; then # dir specified echo -e "dir specified (in command):\n\t$1\n" targetDir=$1 elif [[ -v node_dir_en ]]; then # environable set, echo -e "dir specified (in environment vairable):\n\t$node_dir_en\n" targetDir=$node_dir_en else # environable not set, echo "dir not specified, won't execute" exit fi # check whether dir exists, if [ -d $targetDir ]; then cd $targetDir else echo -e "invalid dir location:\n\t$targetDir\n" exit fi # initial map, declare -A itemMap itemMap=( ["ɪ"]="i" ["ː"]=":" ["ɜ"]="ə" ["ɒ"]="ɔ" ["ʊ"]="u" ["ɛ"]="e") # print item maps, echo 'maps:' for key in "${!itemMap[@]}"; do echo -e "\t$key\t->\t${itemMap[$key]}" done echo -e '\n' # do replace, for key in "${!itemMap[@]}"; do grep -rli "$key" * | xargs -i@ sed -i "s/$key/${itemMap[$key]}/g" @ done echo -e "\nDone." exit 

我正在给一个例子来修复python源代码中的一个常见的shebang错误。

您可以尝试grep / sed方法。 这是一个与GNU sed一起工作,不会破坏git回购:

 $ grep -rli --exclude '*.git*' '#!/usr/bin/python' . | xargs -I {} \ gsed -i '' -e 's/#!\/usr\/bin\/python/#!\/usr\/bin\/env python/' {} 

或者你可以使用greptile 🙂

 $ greptile -x .py -l -i -g '#!/usr/bin/env python' -r '#!/usr/bin/python' . 

我刚刚testing了第一个脚本,第二个脚本也是如此。 小心转义字符,我认为在大多数情况下应该更容易使用greptile。 当然,你可以用sed做很多有趣的事情,为此,最好把它和xargs一起使用。

我发现这个从另一个post(不记得哪一个),而不是最优雅的,这是简单的,作为一个新手Linux用户给了我没有麻烦

 for i in *old_str* ; do mv -v "$i" "${i/\old_str/new_str}" ; done 

如果您有空格或其他特殊字符,请使用\

 for i in *old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done 

对于子目录中的string使用**

 for i in *\*old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done 

$replace“从”“到” – “find / path / to / folder -type f”

(replace – MySQL数据库系统的stringreplace工具)