如何在linux命令行中替换多个文件中的字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11392478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to replace a string in multiple files in linux command line
提问by mridul4c
I need to replace a string in a lot of files in a folder, with only ssh
access to the server. How can I do this?
我需要替换文件夹中许多文件中的字符串,并且只能ssh
访问服务器。我怎样才能做到这一点?
采纳答案by kev
cd /path/to/your/folder
sed -i 's/foo/bar/g' *
Occurrences of "foo" will be replaced with "bar".
“foo”的出现将替换为“bar”。
On BSD systems like macOS, you need to provide a backup extension like -i '.bak'
or else "risk corruption or partial content" per the manpage.
在像 macOS 这样的 BSD 系统上,您需要-i '.bak'
根据联机帮助页提供备份扩展,否则“风险损坏或部分内容”。
cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *
回答by Kaspar L. Palgi
This worked for me:
这对我有用:
find ./ -type f -exec sed -i 's/string1/string2/' {} \;
Howerver, this did not: sed -i 's/string1/string2/g' *
. Maybe "foo" was not meant to be string1 and "bar" not string2.
Howerver,这并不:sed -i 's/string1/string2/g' *
。也许“foo”不是string1,而“bar”不是string2。
回答by pymarco
@kev's answer is good, but only affects files in the immediate directory.The example below uses grep to recursively find files. It works for me everytime.
@kev 的回答很好,但只影响直接目录中的文件。下面的例子使用 grep 递归查找文件。它每次都对我有用。
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
Command breakdown
命令分解
grep -r: --recursive, recursively read all files under each directory.
grep -l: --print-with-matches, prints the name of each file that has a match, instead of printing matching lines.
grep -i: --ignore-case.
grep -r: --recursive,递归读取每个目录下的所有文件。
grep -l: --print-with-matches,打印每个匹配的文件的名称,而不是打印匹配的行。
grep -i: --ignore-case。
xargs: transform the STDIN to arguments, follow this answer.
xargs -i@ ~command contains @~: a placeholder for the argument to be used in a specific position in the ~command~, the @ sign is a placeholder which could replaced by any string.
xargs:将 STDIN 转换为参数,请遵循此答案。
xargs -i@ ~command 包含 @~:用于在~command~ 中特定位置使用的参数的占位符,@ 符号是一个可以被任何字符串替换的占位符。
sed -i: edit files in place, withoutbackups.
sed s/regexp/replacement/: substitute string matching regexpwith replacement.
sed s/regexp/replacement/g: global, make the substitution for each match instead of only the first match.
sed -i:就地编辑文件,无需备份。
SED S /的regexp /更换/:替代字符串匹配正则表达式与更换。
sed s/regexp/replacement/ g: global,对每个匹配进行替换,而不仅仅是第一个匹配。
回答by Céline Aussourd
Similar to Kaspar's answer but with the g flag to replace all the occurrences on a line.
类似于 Kaspar 的答案,但使用 g 标志替换一行中的所有出现。
find ./ -type f -exec sed -i 's/string1/string2/g' {} \;
For global case insensitive:
对于全局不区分大小写:
find ./ -type f -exec sed -i 's/string1/string2/gI' {} \;
回答by Dennis
grep --include={*.php,*.html} -rnl './' -e "old" | xargs -i@ sed -i 's/old/new/g' @
回答by Pawel Dubiel
If you have list of files you can use
如果您有可以使用的文件列表
replace "old_string" "new_string" -- file_name1 file_name2 file_name3
If you have all files you can use
如果您拥有可以使用的所有文件
replace "old_string" "new_string" -- *
If you have list of files with extension, you can use
如果您有带扩展名的文件列表,则可以使用
replace "old_string" "new_string" -- *.extension
回答by Djacomo
To replace a string in multiple files you can use:
要替换多个文件中的字符串,您可以使用:
grep -rl string1 somedir/ | xargs sed -i 's/string1/string2/g'
E.g.
例如
grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'
回答by Anaphory
The stream editor does modify multiple files “inplace” when invoked with the -i
switch, which takes a backup file ending as argument. So
当使用-i
开关调用时,流编辑器确实会“就地”修改多个文件,该开关以备份文件结尾作为参数。所以
sed -i.bak 's/foo/bar/g' *
replaces foo
with bar
in all files in this folder, but does not descend into subfolders. This will however generate a new .bak
file for every file in your directory.
To do this recursively for all files in this directory and all its subdirectories, you need a helper, like find
, to traverse the directory tree.
内容替换foo
与bar
在此文件夹中的所有文件,但不会下降到子文件夹。但是,这将为.bak
目录中的每个文件生成一个新文件。要对该目录及其所有子目录中的所有文件递归执行此操作,您需要一个助手(如find
)来遍历目录树。
find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' *
find
allows you further restrictions on what files to modify, by specifying further arguments like find ./ -name '*.php' -or -name '*.html' -print0
, if necessary.
find
允许您进一步限制要修改的文件find ./ -name '*.php' -or -name '*.html' -print0
,如有必要,可通过指定更多参数(如)。
Note: GNU sed
does not require a file ending, sed -i 's/foo/bar/g' *
will work, as well; FreeBSD sed
demands an extension, but allows a space in between, so sed -i .bak s/foo/bar/g *
works.
注意:GNUsed
不需要文件结尾,sed -i 's/foo/bar/g' *
也可以工作;FreeBSDsed
需要一个扩展,但允许中间有一个空间,所以sed -i .bak s/foo/bar/g *
可以。
回答by BBW Before Windows
script for multiedit command
多编辑命令脚本
multiedit [-n PATTERN] OLDSTRING NEWSTRING
From Kaspar's answer I made a bash script to accept command line arguments and optionally limit the filenames matching a pattern. Save in your $PATH and make executable, then just use the command above.
从 Kaspar 的回答中,我制作了一个 bash 脚本来接受命令行参数并可选择限制与模式匹配的文件名。保存在您的 $PATH 中并使可执行文件,然后只需使用上面的命令。
Here's the script:
这是脚本:
#!/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 [ == "-n" ]; then # if -n option is given:
# replace OLDSTRING with NEWSTRING recursively in files matching PATTERN
find ./ -type f -name "" -exec sed -i "s///g" {} \;
else
# replace OLDSTRING with NEWSTRING recursively in all files
find ./ -type f -exec sed -i "s///" {} \;
fi
回答by Ilya Suzdalnitski
To replace a path within files (avoiding escape characters) you may use the following command:
要替换文件中的路径(避免转义字符),您可以使用以下命令:
sed -i 's@old_path@new_path@g'
The @ sign means that all of the special characters should be ignored in a following string.
@ 符号意味着在后面的字符串中应该忽略所有特殊字符。