只使用grep和sed,如何替换所有出现的:
a.example.com
与
b.example.com
在/home/user/
目录树下的文本文件中递归查找并替换子目录中所有文件中的所有匹配项。
答案 0 :(得分:67)
试试这个:
find /home/user/ -type f | xargs sed -i 's/a.example.com/b.example.com/g'
如果您想忽略点目录
find . \( ! -regex '.*/\..*' \) -type f | xargs sed -i 's/a.example.com/b.example.com/g'
答案 1 :(得分:26)
试试这个:
SELECT pet, hobby, SUM(weight)
FROM weights JOIN pets on weights.person_id=pets.person_ID
JOIN hobbies on weights.person_id=hobbies.person_id
GROUP BY pet, hobby
UNION
SELECT pet, NULL, SUM(weight)
FROM weights JOIN pets on weights.person_id=pets.person_ID
GROUP BY pet
UNION
SELECT NULL, hobby, SUM(weight)
FROM weights JOIN hobbies on weights.person_id=hobbies.person_id
GROUP BY hobby
UNION
SELECT SUM(weight)
FROM weights
grep -rl 'SearchString' ./ | xargs sed -i 's/REPLACESTRING/WITHTHIS/g'
将递归搜索目录grep -rl
中的SEARCHSTRING
,并使用./
替换字符串。
例如:
使用sed
中的TOM
搜索字符串替换名称JERRY
SWATKATS
CARTOONNETWORK
这将在grep -rl 'SWATKATS' CARTOONNETWORK/ | xargs sed -i 's/TOM/JERRY/g'
下的所有文件和子目录中将TOM
替换为JERRY
,只要它找到字符串CARTOONNETWORK
。
答案 2 :(得分:4)
我知道这是一个非常古老的问题,但是......
find
和xargs
时, @ vehomzzz的答案会使用grep
和sed
。
@EmployedRussian和@BrooksMoses试图说它是awk
和sed
的副本,但它不是 - 再次,问题明确地说grep
和sed
仅。
所以这是我的解决方案,假设你使用Bash作为你的shell:
OLDIFS=$IFS
IFS=$'\n'
for f in `grep -rl a.example.com .` # Use -irl instead of -rl for case insensitive search
do
sed -i 's/a\.example\.com/b.example.com/g' $f # Use /gi instead of /g for case insensitive search
done
IFS=$OLDIFS
如果您使用的是其他shell,例如Unix SHell,请告诉我,我会尝试找到语法调整。
P.S。:这是一个单行:
OLDIFS=$IFS;IFS=$'\n';for f in `grep -rl a.example.com .`;do sed -i 's/a\.example\.com/b.example.com/g' $f;done;IFS=$OLDIFS
来源:
答案 3 :(得分:2)
对我来说,下一个命令是:
find /path/to/dir -name "file.txt" | xargs sed -i 's/string_to_replace/new_string/g'
如果string包含斜杠'path / to / dir',则可以将其替换为另一个要分隔的字符,例如'@'而不是'/'。
例如:'s@string/to/replace@new/string@g'
答案 4 :(得分:1)
尝试此命令:
/home/user/ directory - find ./ -type f \
-exec sed -i -e 's/a.example.com/b.example.com/g' {} \;
答案 5 :(得分:1)
它比那简单得多。
for i in `find *` ; do sed -i -- 's/search string/target string/g' $i;
完成强>
find i
=>将把文件夹和子文件夹中的所有文件引入SED。
sed -i
=>将在文件中替换相关字符串(如果存在)。
答案 6 :(得分:1)
我们可以尝试使用更强大的 ripgrep 作为
rg "BYE_BYE_TEXT" ./ --files-with-matches | xargs sed -i "s/BYE_BYE_TEXT/WELCOME_TEXT/g"
因为 ripgrep 擅长查找而 sed 擅长替换。
答案 7 :(得分:0)
下面的命令将以递归方式搜索其名称与搜索模式匹配的所有文件,并将替换字符串:
find /path/to/searchdir/ -name "serachpatter" -type f | xargs sed -i 's/stringone/StrIngTwo/g'
此外,如果您想限制递归的深度,您也可以设置限制:
find /path/to/searchdir/ -name "serachpatter" -type f -maxdepth 4 -mindepth 2 | xargs sed -i 's/stringone/StrIngTwo/g'
答案 8 :(得分:0)
在macOS上,没有答案对我有用。我发现这是由于与GNU相比sed
在macOS和其他BSD系统上的工作方式不同。
尤其是BSD sed
takes the -i
option but requires a suffix for the backup (but an empty suffix is permitted)
grep
版本。
grep -rl 'foo' ./ | LC_ALL=C xargs sed -i '' 's/foo/bar/g'
来自this answer的 find
版本。
find . \( ! -regex '.*/\..*' \) -type f | LC_ALL=C xargs sed -i '' 's/foo/bar/g'
如果您在Git存储库中,请不要忽略正则表达式以忽略.
文件夹。我意识到这很困难!
该LC_ALL=C
选项用于avoid getting sed: RE error: illegal byte sequence
if sed
finds a byte sequence that is not a valid UTF-8 character。这是BSD和GNU之间的另一个区别。根据您要处理的文件类型,您可能不需要它。
由于某些我不清楚的原因,发现grep
版本比find
版本更多,这就是为什么我建议使用grep
的原因。