sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext
我需要将上面的整行替换为
>
搜索关键字是
TEXT_TO_BE_REPLACED
我需要为此编写一个shell脚本。如何使用
sed
实现此目的?#1 楼
您可以使用change命令替换整行,并使用-i
标志进行就地更改。例如,使用GNU sed:sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
#2 楼
在替换整行之前和之后,您需要使用通配符(.*
):sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./'
评论
谢谢,让我的工作正常了:sed's /.* <表达式>。* / <表达式> SE_LABEL = ABC <表达式> / g'MYR2.xml> test.txt
– Nasri Najib
14-10-24在7:46
这可以在Mac OS X Yosemite上工作,但我使用-i和-e标志的情况如下:sed -i -e“ s /.* search_string。* / Replacement_line /'file_being_searched.txt
–肯特·布尔
2014-12-27 19:24
@KentJohnson我认为您的命令中的引号不匹配。
–哈希危害
15年8月12日在16:34
@MBarnett你是对的,我应该在这里用两个双引号引起来。
–肯特·布尔
2015年9月5日,下午1:25
仅提供完整信息。要使其就位,可以添加-i选项
– Temak
2015年11月5日,12:20
#3 楼
接受的答案对我不起作用有几个原因:我的sed版本不喜欢扩展长度为零的
-i
c\
命令的语法很奇怪,并且我无法使它正常工作我没有意识到我的某些问题来自未转义的斜杠
所以这是我想出的解决方案,我认为该解决方案最适合案例:
function escape_slashes {
sed 's/\//\\//g'
}
function change_line {
local OLD_LINE_PATTERN=; shift
local NEW_LINE=; shift
local FILE=
local NEW=$(echo "${NEW_LINE}" | escape_slashes)
sed -i .bak '/'"${OLD_LINE_PATTERN}"'/s/.*/'"${NEW}"'/' "${FILE}"
mv "${FILE}.bak" /tmp/
}
因此使用样本来解决所提出的问题:
change_line "TEXT_TO_BE_REPLACED" "This line is removed by the admin." yourFile
#4 楼
上面的答案:sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
如果替换字符串/行不是变量,则可以正常工作。
问题是在Redhat 5上,
\
之后的c
逃脱了$
。双\
也不起作用(至少在Redhat 5上有效)。通过反复尝试,我发现如果替换字符串/行仅是一行,则
\
之后的c
是多余的。因此,我在\
之后没有使用c
,而是将变量用作单个替换行,这很令人高兴。代码类似于:
sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo
请注意使用双引号而不是单引号。
评论
您仍然可以像这样使用单引号:sed -i'/ TEXT_TO_BE_REPLACED / c'“ $ VARIABLE”“ / tmp / foo
–阿利斯泰尔·麦金太尔(Alistair McIntyre)
19 Mar 4 '19 at 13:20
此变体适用于Ubuntu / Debian:sed -i“ / TEXT_TO_BE_REPLACED / c \\ $ REPLACEMENT_TEXT_STRING” / tmp / foo
–杰西·尼克尔斯(Jesse Nickles)
20年7月25日在11:59
#5 楼
到目前为止,所有提供的答案都假定您对要替换的文本有所了解,这很有意义,因为这就是OP的要求。我提供的答案是假定您对要替换的文本一无所知,并且文件中可能有单独的行,具有与您要替换的内容相同或相似的内容。此外,假设您知道要替换的行的行号。以下示例演示了按特定行号删除或更改文本的方法:
< pre class =“ lang-bash prettyprint-override”>
# replace line 17 with some replacement text and make changes in file (-i switch)
# the "-i" switch indicates that we want to change the file. Leave it out if you'd
# just like to see the potential changes output to the terminal window.
# "17s" indicates that we're searching line 17
# ".*" indicates that we want to change the text of the entire line
# "REPLACEMENT-TEXT" is the new text to put on that line
# "PATH-TO-FILE" tells us what file to operate on
sed -i '17s/.*/REPLACEMENT-TEXT/' PATH-TO-FILE
# replace specific text on line 3
sed -i '3s/TEXT-TO-REPLACE/REPLACEMENT-TEXT/'
#6 楼
用于操纵配置文件的方法我想出了这个受skensell启发的解决方案。 >
如果不存在则创建文件
替换searchPattern匹配的整行(所有行)
如果找不到模式,则在文件末尾添加replaceLine
功能:
function configLine {
local OLD_LINE_PATTERN=; shift
local NEW_LINE=; shift
local FILE=
local NEW=$(echo "${NEW_LINE}" | sed 's/\//\\//g')
touch "${FILE}"
sed -i '/'"${OLD_LINE_PATTERN}"'/{s/.*/'"${NEW}"'/;h};${x;/./{x;q100};x}' "${FILE}"
if [[ $? -ne 100 ]] && [[ ${NEW_LINE} != '' ]]
then
echo "${NEW_LINE}" >> "${FILE}"
fi
}
疯狂退出状态魔术来自https://stackoverflow.com/a/12145797/1262663
#7 楼
bash-4.1$ new_db_host="DB_HOSTNAME=good replaced with 122.334.567.90"
bash-4.1$
bash-4.1$ sed -i "/DB_HOST/c $new_db_host" test4sed
vim test4sed
'
'
'
DB_HOSTNAME=good replaced with 122.334.567.90
'
工作正常
#8 楼
在我的makefile文件中,我使用以下命令:还要更改模式以替换。示例输出: “修订:1190”显然与您将它们定义为“修订:”不同...
#9 楼
cat find_replace | while read pattern replacement ; do
sed -i "/${pattern}/c ${replacement}" file
done
find_replace文件包含2列,c1带有要匹配的模式,c2带有替换,sed循环替换每一行,其中包含变量1的模式之一评论
不,这在很多方面都是错误的。使用包含您要执行的所有替换的脚本文件运行sed一次。在同一文件上重复运行sed -i是一个可怕的反模式。
–tripleee
18/12/12在6:46
#10 楼
为此,无需依赖任何GNUism,例如-i
不带参数或c
不带换行符: sed '/TEXT_TO_BE_REPLACED/c\
This line is removed by the admin.
' infile > tmpfile && mv tmpfile infile
命令形式)
c\
text
text
可以由一行或多行组成,必须转义应成为替换内容的换行符: c\
line1\
line2
s/x/y/
其中模式空间已被两行替换后,
s/x/y/
是新的sed命令。line1
line2
#11 楼
将包含指定字符串的整行替换为该行的内容文本文件:
Row: 0 last_time_contacted=0, display_name=Mozart, _id=100, phonebook_bucket_alt=2
Row: 1 last_time_contacted=0, display_name=Bach, _id=101, phonebook_bucket_alt=2
单个字符串:
$ sed 's/.* display_name=\([[:alpha:]]\+\).*//'
output:
100
101
多个由空格分隔的字符串:
$ sed 's/.* display_name=\([[:alpha:]]\+\).* _id=\([[:digit:]]\+\).*/ /'
output:
Mozart 100
Bach 101
调整正则表达式以满足您的需求
[:alpha]和[:digit:]
是字符类和括号表达式
#12 楼
与上面的类似。sed 's/[A-Za-z0-9]*TEXT_TO_BE_REPLACED.[A-Za-z0-9]*/This line is removed by the admin./'
评论
将FOO = TEXT_TO_BE_REPLACED更改为FOO =此行...因此不符合规范。
–詹斯
13年5月30日在9:18
是的。我们的要求是将整个行替换为“该行已被管理员删除”。如果找到密钥模式“ TEXT_TO_BE_REPLACED”。上面的命令令人满意。如果我的理解是错误的,请纠正我。
– Anapureddy Hari
2013年6月6日14:20
@AnnapureddyHari如果搜索字符串之前或之后的文本中除了A-Za-z0-9之外还包含其他任何内容,则此答案不起作用。正如詹斯指出的那样,如果存在等号则失败。 “ FOO =”部分将保留;您尚未替换整行。该代码是关于文件中可能存在的内容的短视记录。如果您的意思是通配符,则应输入通配符,如Thor的答案所示。
–msouth
16年5月7日在21:37
#13 楼
下面的命令为我工作。正在使用变量sed -i "/\<$E\>/c $D" "$B"
评论
但是我的新要求是在替换时对SKIP注释(以#开头)行。当我们替换完整行时,这也将替换注释行,并且您最终将获得重复的属性。如果有人对此有解决方案,请告诉我。
–Ritesh Borkar
19-09-19在9:24
您所说的“重复属性”是什么意思?要取消匹配您使用的地址!地址。
–拉吉布
20-10-26在15:50
#14 楼
我经常使用正则表达式从文件中提取数据,而我只是用正则表达式用\"
代替文字引号//
什么都没有:-) cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed s/\"//g | cut -d, -f1 > list.txt
评论
请注意,在c \之前需要一个空格。我刚刚进行了编辑以添加此内容。
–马库斯·唐宁(Marcus Downing)
2014年3月17日在12:58
@MarcusDowning GNU sed不需要空格;它可以像最初发布的一样正常工作。如果您的特定sed需要空格,则一定要注意哪个sed不兼容,并添加必要的调用作为注释。但是,请不要在可接受的答案中更改工作代码。
–托德·雅各布斯(Todd A. Jacobs)
2014年3月17日14:08
如何使用变量代替文本“ This ...”?如果我将其替换为$ variable,它不会显示其内容,但会显示变量名称。
–史蒂文
2014年11月26日下午16:47
直接在变量后面跟随c \时存在问题:…c \ $ VAR ...反斜杠将转义美元。在这种情况下,我(在Ubuntu 15.10上使用bash / sed)必须编写…c \\ $ VAR…
– Jan
2015年11月9日在9:45
在Mac上使用:sed -i'''/ TEXT_TO_BE_REPLACED / c \此行已由管理员删除。 / tmp / foo; (当第一个参数为空时,它将编辑文件中的文件,否则创建备份)
– AndreDurao
18年4月10日在11:19