Bash 如何用新文本替换多个文本行

Bash 如何用新文本替换多个文本行,bash,shell,command-line,ubuntu-18.04,Bash,Shell,Command Line,Ubuntu 18.04,我有: 我想用 SIESTA_ARCH = unknown CC = gcc FPP = $(FC) -E -P -x c FC = gfortran 在bash中,您可以定义如下函数(只需在终端或脚本中执行这一行): 然后,您可以在任何文件中替换所需的任何文字字符串,例如: function repl() { FIND="$2" REPLACE="$3" ruby -p -i -e "gsub(ENV['FIND'], ENV['REPLACE'])" "$1"; } 请注意,这将替换

我有:

我想用

SIESTA_ARCH = unknown
CC = gcc
FPP = $(FC) -E -P -x c 
FC = gfortran 

在bash中,您可以定义如下函数(只需在终端或脚本中执行这一行):

然后,您可以在任何文件中替换所需的任何文字字符串,例如:

function repl() { FIND="$2" REPLACE="$3" ruby -p -i -e "gsub(ENV['FIND'], ENV['REPLACE'])" "$1"; }

请注意,这将替换指定文件中出现的所有此类字符串。

我想下一个解决方案适合您(根据PO的答案编辑的解决方案)

script.sed

repl ~/Code/Makefile 'SIESTA_ARCH = unknown' 'SIESTA_ARCH = amd64 (x86_64)'
repl ~/Code/Makefile 'CC = gcc' 'CC = mpicc'
repl ~/Code/Makefile 'FC = gfortran' 'FC = mpif90'
调用as
/script.sed Makefile
查看标准输出的结果,或调用as
/script.sed-i Makefile
更新文件
Makefile


此解决方案将所有出现的
SIESTA\u ARCH=unknown
和下一个行块更改为新值,直到以
FC=
开头的行

如果您有
ed

cat script.ed
对文件使用脚本

ed-s Makefile
输出

SIESTA\u ARCH=amd64(x86\u 64)
CC=mpicc
FPP=$(FC)-E-P-xc
FC=gfortran
现在将
、pq
更改为
w
Q
,以就地编辑文件

H
g/^\(SIESTA_ARCH =\)\(.\+\)$/s//\1 amd64 (x86_64)/
g/^\(CC =\)\(.\+\)$/s//\1 mpicc/
,p
Q
ed-s Makefile
到目前为止,您尝试了什么?我们是否必须理解,您要处理的行通常包含字符串“First line”,等等@Pierre François我再次编辑了我的问题谢谢你,但下次请不要包括我们无法复制/粘贴用于测试的屏幕截图。这一次,我将为你编辑这个问题。你是想要一个你能做到这一点的所有方法的概要,还是仅仅想要一个有效的?是否必须将其视为块,或者是否应该(可以)将其视为3个不同的单行更改,以便在一次编辑操作中应用?您可以使用
sed
awk
perl
python
ruby
来完成任务;他们中的任何一个人都会镇定自若地这样做。再努力一点,也有其他的选择-
ed
ex
。代码应该验证该行是否如您所期望的那样,还是只是查找标记(直到等号)并用所需的输出替换该行?@RavinderSingh13我希望将其全部替换为假定海报已安装了ruby,并且知道如何使用(of)它。@Roadowl不,我不知道它至少是一个选项,而且在许多情况下,
ruby
将已经可用,用户无需显式安装任何东西,您只需使用
ruby--version
检查是否存在。关于
ruby
,您不需要了解更多,就可以使用它了。是的,在我的makefile中有许多“CC”和“FC”,我只想更改特定的。如果您不想更改以
CC=
开头的所有行,请编辑您的问题,指定在何种情况下必须更新这些行。例如:对于所有出现的
SIESTA\u ARCH=unknown
SIESTA\u ARCH=amd64(x86\u 64)
中的这一行更改为
SIESTA\u ARCH=amd64(x86\u 64)
,并在紧接着的3行(或4行)中,将
CC=…
更改为
CC=mpicc
,并将
FP=…
更改为
FC=mpif90
。根据您的回答,我将发布解决方案。根据您在评论中的要求,我已将代码更新为仅在块上工作。编辑您的问题以澄清这一点是个好主意。我建议您也添加一些不能更改的输入,以检查建议的解决方案是否正常工作。如果您更新了问题,请解释如何定义块。例如,一组以
SIESTA\u ARCH=unknown
开头的行,在以
FC=
开头的行之后停止。此解决方案将更改
CC=
的所有出现。这不是PO想要的;据我所知,他只想更改SIESTA\u ARCH=unknown
后面的块中出现的
CC=
#!/bin/sed -f

/^SIESTA_ARCH = unknown/,/^FC =/{
  s/^SIESTA_ARCH =.*/SIESTA_ARCH = amd64 (x86_64)/
  s/^CC =.*/CC = mpicc/
  s/^FC =.*/FC = mpif90/
}
H
g/^\(SIESTA_ARCH =\)\(.\+\)$/s//\1 amd64 (x86_64)/
g/^\(CC =\)\(.\+\)$/s//\1 mpicc/
,p
Q
H
g/^\(SIESTA_ARCH =\)\(.\+\)$/s//\1 amd64 (x86_64)/
g/^\(CC =\)\(.\+\)$/s//\1 mpicc/
w
q