假设我有以下句子:
jack and jill
climbs up a hill
我想在文件中搜索hill
并将jill
替换为jerry
,即hill
上方的行,{{1}}保持原样。是否可以使用vim编辑器或awk / sed?
答案 0 :(得分:5)
使用GNU sed:
sed 'N;/\n.*hill/s/jill\(.*[^\n]\)/jerry\1/' file
N
:将下一行添加到模式空间/\n.*hill/
:如果在新行之后找到hill
s/jill\(.*[^\n]\)/
:替换在新线之前找到的jill
以及跟随捕获的字符jerry\1
:jerry
字符串后跟捕获的字符要编辑文件,请尝试-i
标记:
sed -i 'N;/\n.*hill/s/jill\(.*[^\n]\)/jerry\1/' file
答案 1 :(得分:3)
查找和替换的基本语法
<强>桑达强>
sed 's/word_to_find/word_to_replace/g' inputfile
要更新文件,请通过-i
选项
sed -i 's/word_to_find/word_to_replace/g' inputfile
<强> GAWK 强>
gawk -i inplace '{gsub(/find/,"replace"); print}' inputfile
<强> AWK 强>
写入somefile然后重命名
awk '{ gsub(/find/,"replace"); print }' inputfile >outputfile
结束时的快捷方式1
执行默认操作打印当前记录/行/行
awk 'gsub(/find/,"replace") + 1' inputfile >outputfile
- 编辑 -
<强>结果
$ cat f
jack and jill
climbs up a hill
$ awk '/hill/{gsub(/jill/,"jerry",prev);h=0;if(prev)print prev;print;prev="";next} h{print prev} {prev=$0; h=1}' f
jack and jerry
climbs up a hill
更好的可读性
awk '/hill/{
gsub(/jill/,"jerry",prev);
h=0;
if(prev)print prev;
print;
prev="";
next
}
h{
print prev
}
{
prev=$0; h=1
}
' f
经过
测试<强>输入强>
$ cat f
jack and jill
climbs up a hill
jack and jill
climbs up a a
climbs up a hill
climbs up a a
climbs up a hill
jill
climbs up a hill
climbs up a hill
<强>输出强>
$ awk '/hill/{gsub(/jill/,"jerry",prev);h=0;if(prev)print prev;print;prev="";next} h{print prev} {prev=$0; h=1}' f
jack and jerry
climbs up a hill
jack and jill
climbs up a a
climbs up a hill
climbs up a a
climbs up a hill
jerry
climbs up a hill
climbs up a hill
答案 2 :(得分:2)
尝试以下:
解决方案1:我认为你必须只替换第一次出现的jill。
awk '/hill/{sub(/jill/,"jerry")}1' Input_file
解决方案第二:我在考虑你必须替换所有出现的jill。
awk '/hill/{gsub(/jill/,"jerry")}1' Input_file
解决方案3:如果您想将此新更改保存到Input_file本身,那么以下内容可能有所帮助。(放置sub / gsub以替换一次/多次出现的字符串)
awk '/hill/{sub(/jill/,"jerry")}1' Input_file > temp_Input_file && mv temp_Input_file Input_file
编辑:以上解决方案将在字符串jill和hill位于同一行时起作用,在OP的帖子编辑后,这些字符串似乎不在同一行,因此以下可能会有所帮助
awk '/jill/{val=$0;getline;if($0 ~ /hill/){sub(/jill/,"jerry",val);print val ORS $0};next} 1' Input_file
答案 3 :(得分:2)
在awk中,考虑.preventDefault()
和hill
是整个单词,而不是更长字符串的一部分。首先,一些测试数据:
jill
代码:
jack and jill
climbs up a hill
then jill silly
saws a hillbilly
cookin them jills
on a prec- hill
答案 4 :(得分:2)
使用vim这可以像
一样简单:g starts a global command
/hill searches for hill
/-1 set the range to the previous line
s/jill/jerry substitute jill with jerry
<强>击穿强>
jill
<强>其它强>
/g
,请添加\<jill\>
答案 5 :(得分:1)
来自Linux.com:
Vim tips: The basics of search and replace
如果要搜索文本字符串并将其替换为另一个文本字符串,可以使用以下语法:[range] s / search / replace /。范围是可选的;如果您只运行:s / search / replace /,它将仅搜索当前行并仅匹配术语的第一个匹配项。
大多数时候,这还不够,所以你可以添加这样的范围:
:8,10秒/ search / replace / g
在该示例中,范围从第8行到第10行。我还添加了&#34;全局&#34;选项,告诉Vim替换一行中的每一个事件,而不仅仅是第一次出现。在不添加g的情况下,您的搜索将仅匹配任何给定行中字符串的第一个实例。
指定范围的另一种方法是进入可视模式并选择要搜索的行,然后按:进入命令模式。要从正常模式进入可视模式,请按v选择常规可视模式,或按V选择行选择,或按Ctrl-v选择块选择。然后在可视模式下选择范围并按:,然后按您要使用的搜索命令。
如果要搜索整个文件,可以使用%来表示该范围:
:%s / search / replace / g
如果您愿意,也可以使用sed,该问题已经得到解答here。
答案 6 :(得分:1)
为什么不用Perl?
perl -ne '$last =~ s/jill/jerry/ if(/hill/); print $last; $last = $_; END { print $last;}' file
稍微可读的版本:
$last =~ s/jill/jerry/ if($_ =~ /hill/);
print $last;
$last = $_;
END {
print $last;
}