AWK 作为一种文本处理实用程序,非常适合此类任务。它可以基于正则表达式进行简单的替换和更高级的替换。它提供了两个功能:sub()和gsub()。第一个仅替换第一次出现,而第二个 - 替换整个字符串中的出现。例如,如果我们有 string one potato two potato,这将是结果:
$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana
$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'
one banana two potato
#!/usr/bin/env python
import sys
import os
import tempfile
tmp=tempfile.mkstemp()
with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
for line in fd1:
line = line.replace('blue','azure')
fd2.write(line)
os.rename(tmp[1],sys.argv[1])
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog
< strin另一种可能比> strout使用管道更有意义的方法!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai
The quick brown fox jumped over the lazy sleeping dog
rgr ('rgr') version 0.1.0
RipGrep Replace (rgr). This program is a wrapper around RipGrep ('rg') in order to allow some
extra features, such as find and replace in-place in files. It doesn't rely on 'sed'. It uses
RipGrep only. Since it's a wrapper around 'rg', it forwards all options to 'rg', so you can use it
as a permanent replacement for 'rg' if you like.
Currently, the only significant new option added is '-R' or '--Replace', which is the same as
RipGrep's '-r' except it MODIFIES THE FILES IN-PLACE ON YOUR FILESYSTEM! This is great! If you
think so too, go and star this project (link below).
USAGE (exact same as 'rg')
rgr [options] <regex> [paths...]
OPTIONS
ALL OPTIONS ACCEPTED BY RIPGREP ('rg') ARE ALSO ACCEPTED BY THIS PROGRAM. Here are just a few
of the options I've amended and/or would like to highlight. Not all Ripgrep options have been
tested, and not all of them ever will be by me at least.
-h, -?, --help
Print help menu
-v, --version
Print version information.
--run_tests
Run unit tests (none yet).
-d, --debug
Turn on debug prints. '-d' is not part of 'rg' but if you use either of these options here
it will auto-forward '--debug' to 'rg' under-the-hood.
-r <replacement_text>, --replace <replacement_text>
Do a dry-run to replace all matches of regular expression 'regex' with 'replacement_text'.
This only does the replacement in the stdout output; it does NOT modify your disk!
-R <replacement_text>, --Replace <replacement_text>
THIS IS THE ONE! Bingo! This is the sole purpose for the creation of this wrapper. This
option will actually replace all matches of regular expression 'regex' with
'replacement_text' ON YOUR DISK. It actually modifies your file system! This is great
for large code-wide replacements when programming in large repos, for instance.
--stats
Show detailed statistics about the ripgrep search and replacements made.
SEE ALSO 'rg -h' AND 'man rg' FOR THE FULL HELP MENU OF RIPGREP ITSELF, WHICH OPTIONS ARE ALSO
ALLOWED AND PASSED THROUGH BY THIS 'rgr' WRAPPER PROGRAM.
EXAMPLE USAGES:
rgr foo -r boo
Do a *dry run* to replace all instances of 'foo' with 'boo' in this folder and down.
rgr foo -R boo
ACTUALLY REPLACE ON YOUR DISK all instances of 'foo' with 'boo' in this folder and down.
rgr foo -R boo file1.c file2.c file3.c
Same as above, but only in these 3 files.
rgr foo -R boo -g '*.txt'
Use a glob filter to replace on your disk all instances of 'foo' with 'boo' in .txt files
ONLY, inside this folder and down. Learn more about RipGrep's glob feature here:
https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#manual-filtering-globs
rgr foo -R boo --stats
Replace on your disk all instances of 'foo' with 'boo', showing detailed statistics.
Note to self: the only free lowercase letters not yet used by 'rg' as of 3 Jan. 2021 are:
-d, -k, -y
This program is part of eRCaGuy_dotfiles: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles
by Gabriel Staples.
解释:
sed
= 流编辑器-i
=就地(即保存回原始文件)命令字符串:
s
= 替代命令original
= 描述要替换的单词(或只是单词本身)的正则表达式new
= 替换它的文本g
= 全局(即全部替换而不只是第一次出现)file.txt
= 文件名有很多方法可以实现它。根据尝试通过字符串替换实现的复杂性,以及根据用户熟悉的工具,某些方法可能比其他方法更受欢迎。
在这个答案中,我使用的是简单
input.txt
文件,您可以使用它来测试此处提供的所有示例。文件内容:重击
Bash 并不是真正用于文本处理,但可以通过参数扩展来完成简单的替换,特别是在这里我们可以使用简单的结构
${parameter/old_string/new_string}
。这个小脚本不会进行就地替换,这意味着您必须将新文本保存到新文件中,并删除旧文件,或者
mv new.txt old.txt
旁注:如果您对为什么
while IFS= read -r ; do ... done < input.txt
使用它感到好奇,它基本上是 shell 逐行读取文件的方式。请参阅此内容以供参考。AWK
AWK 作为一种文本处理实用程序,非常适合此类任务。它可以基于正则表达式进行简单的替换和更高级的替换。它提供了两个功能:
sub()
和gsub()
。第一个仅替换第一次出现,而第二个 - 替换整个字符串中的出现。例如,如果我们有 stringone potato two potato
,这将是结果:AWK 可以将输入文件作为参数,因此使用
input.txt
, 做同样的事情会很容易:根据您拥有的 AWK 版本,它可能有也可能没有就地编辑,因此通常的做法是保存并替换新文本。例如这样的:
SED
Sed 是一个行编辑器。它也使用正则表达式,但对于简单的替换,这样做就足够了:
这个工具的好处是它具有就地编辑功能,您可以使用
-i
标志启用它。Perl
Perl 是另一种经常用于文本处理的工具,但它是一种通用语言,用于网络、系统管理、桌面应用程序和许多其他地方。它从 C、sed、awk 等其他语言中借鉴了许多概念/功能。可以这样进行简单的替换:
与 sed 一样,perl 也有 -i 标志。
Python
这种语言非常通用,也用于各种应用程序。它有很多处理字符串的函数,其中是
replace()
,所以如果你有变量 likevar="Hello World"
,你可以做var.replace("Hello","Good Morning")
读取文件并替换其中的字符串的简单方法如下:
但是,使用 Python,您还需要输出到新文件,您也可以在脚本本身中执行此操作。例如,这是一个简单的:
该脚本将
input.txt
作为命令行参数调用。使用命令行参数运行 python 脚本的确切命令是或者
当然,请确保它
./myscript.py
在您当前的工作目录中,并且对于第一种方式,确保将其设置为可执行文件chmod +x ./myscript.py
Python也可以有正则表达式,特别是有
re
模块,有re.sub()
功能,可以用来做更高级的替换。有许多不同的方法可以做到这一点。一种是使用
sed
和正则表达式。SED 是用于过滤和转换文本的流编辑器。一个例子如下:< strin
另一种可能比> strout
使用管道更有意义的方法!你可以在 Ex 模式下使用 Vim:
%
选择所有行s
代替g
替换每行中的所有实例x
写入是否已进行更改(已更改)并退出通过 awk 的 gsub 命令,
例子:
在上面的示例中,所有 1 都被 0 替换,而不管它位于哪个列。
如果您想在特定列上进行替换,请这样做,
例子:
它仅在第一列将 1 替换为 0。
通过 Perl,
sed
是s tream ed itor,因为您可以使用|
(pipe) 发送标准流(特别是 STDIN 和 STDOUT)sed
并以编程方式即时更改它们,使其成为 Unix 哲学传统中的便捷工具;-i
但也可以使用下面提到的参数直接编辑文件。考虑以下内容:
s/
用于将找到的表达式替换few
为asd
:/g
代表“全局”,意思是对整条线都这样做。如果您不使用/g
(使用s/few/asd/
,无论如何总是需要三个斜杠)并few
在同一行出现两次,则只有第一个few
更改为asd
:这在某些情况下很有用,例如更改行首的特殊字符(例如,将某些人用来在电子邮件线程中引用先前材料的大于符号替换为水平制表符,同时在行的后面留下引用的代数不等式未触及),但在您的示例中,您指定在任何地方
few
都应该替换它,请确保您拥有/g
.以下两个选项(标志)合并为一个,
-ie
:-i
选项用于就地编辑文件hello.txt
。-e
option 表示要运行的表达式/命令,在这种情况下为s/
.注意:
-i -e
用于搜索/替换很重要。如果这样做-ie
,您将创建每个文件的备份,并附加字母“e”。你可以这样做:
示例:要在所有由 locate 命令产生的文件中用 [logdir', os.getcwd()] 替换所有出现的 [logdir', ''] (不带 [] ),请执行以下操作:
例1:
例 2:
其中 [tensorboard/program.py] 是要搜索的文件
跨多个文件查找和替换
为了在大型文件系统(例如巨大的代码库)中查找和替换多个文件(甚至可能是数千或数百万)时尽可能接近闪电般的速度或扭曲速度,我建议使用 Ripgrep (
rg
),它非常棒且速度极快. 不幸的是,它不支持在文件中查找和替换,据作者说可能永远不会,所以我们必须使用一些变通方法。基于 Ripgrep 的方法 1(简单但更有限的 1-liner)
这是第一个解决方法:https ://github.com/BurntSushi/ripgrep/issues/74#issuecomment-376659557
使用 Ripgrep (
rg
) 查找包含匹配项的文件,然后通过管道将这些文件的列表用于在这些文件中sed
进行文本替换:基于 Ripgrep 的方法 2(我推荐的选择)
这是第二个解决方法:使用我在 Ripgrep 周围编写的
rgr
(Ripgrep Replace) 包装脚本,它添加了-R
替换磁盘上内容的选项。安装简单。只需按照该文件顶部的说明进行操作即可。用法也超级简单:由于它是 的包装器
rg
,它还提供对 Ripgrep 的所有其他选项和功能的访问。这是目前完整的帮助菜单,还有更多使用示例:Ripgrep 安装
对于 Ubuntu 20.04 或更高版本:
对于早期版本的 Ubuntu,请按照此处的 Debian 说明进行操作:https ://github.com/BurntSushi/ripgrep#installation