我有一个文本文件,其中有一个特定的行,例如
sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext
我需要将上面的整行替换为
This line is removed by the admin.
搜索关键字是 TEXT_TO_BE_REPLACED
我需要为此编写一个shell脚本。我该如何使用sed
呢?
我有一个文本文件,其中有一个特定的行,例如
sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext
我需要将上面的整行替换为
This line is removed by the admin.
搜索关键字是 TEXT_TO_BE_REPLACED
我需要为此编写一个shell脚本。我该如何使用sed
呢?
Answers:
您可以使用change命令替换整行,并使用该-i
标志就地进行更改。例如,使用GNU sed:
sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
c\
直接在变量后面跟随时有一个问题:…c\$VAR…
反斜杠将使美元转义。在这种情况下,我(Ubuntu 15.10上的bash / sed)不得不写…c\\$VAR…
sed -i '' '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
; (当第一个参数为空时,它将编辑文件中的文件,否则创建备份)
您需要在.*
前后使用通配符()替换整行:
sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./'
sed -i -e "s/.*search_string.*/Replacement_line/' file_being_searched.txt
-i
接受的答案对我不起作用有以下几个原因:
-i
扩展名为零c\
命令的语法很奇怪,我无法使其正常工作因此,这是我想出的解决方案,我认为该解决方案适用于大多数情况:
function escape_slashes {
sed 's/\//\\\//g'
}
function change_line {
local OLD_LINE_PATTERN=$1; shift
local NEW_LINE=$1; shift
local FILE=$1
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
上面的答案:
sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo
如果替换字符串/行不是变量,则可以正常工作。
问题是在Redhat 5 \
上c
越狱后$
。双重\\
也不起作用(至少在Redhat 5上)。
通过命中和尝试,我发现如果替换字符串/行仅是一行,则\
after c
是多余的。因此,我没有\
在之后使用c
,而是将变量用作单个替换行,这很令人高兴。
代码如下所示:
sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo
请注意使用双引号而不是单引号。
到目前为止,所有提供的答案都假定您对要替换的文本有所了解,这很有意义,因为这就是OP的要求。我提供的答案是假设您对要替换的文本一无所知,并且文件中可能有单独的一行,具有与您要替换的内容相同或相似的内容。此外,假设您知道要替换的行的行号。
下面的示例演示通过特定的行号删除或更改文本:
# 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/'
用于配置文件的操作
我想出了这个受skensell回答启发的解决方案
configLine [searchPattern] [replaceLine] [filePath]
它会:
功能:
function configLine {
local OLD_LINE_PATTERN=$1; shift
local NEW_LINE=$1; shift
local FILE=$1
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
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
反复在同一个文件上运行是一种可怕的反模式。
与上面的类似。
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=This line ...
使不符合规范。
下面的命令为我工作。哪个正在使用变量
sed -i "/\<$E\>/c $D" "$B"