我想知道如何替换整个文件中第一次出现的搜索模式。例如,
import java.io.File;
import java.io.File;
应替换为
import java.io.IOException;
import java.io.File;
如何使用sed实现这一目标? 谢谢
答案 0 :(得分:2)
当它只需要替换来完成一行中的所有工作时,当然不需要编写一些大的长脚本。您只需为工作选择合适的电动工具。
这是一个Perl单行:
% cat -n /tmp/f
1 import java.lang.Character;
2 import java.io.File;
3 import java.io.File;
4 import java.util.Pattern;
% perl -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f
import java.lang.Character;
import java.io.IoException;
import java.io.File;
import java.util.Pattern;
如果你想通过编辑文件来完成,只需添加 -i.bak :
% perl -i.bak -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f
% head /tmp/f{,.bak}
==> /tmp/f <==
import java.lang.Character;
import java.io.IoException;
import java.io.File;
import java.util.Pattern;
==> /tmp/f.bak <==
import java.lang.Character;
import java.io.File;
import java.io.File;
import java.util.Pattern;
可行的原因是,当您为m//
运算符赋予??
分隔符时,它具有一些内置状态,以便记住仅匹配第一次。
然后在替代品中,空模式意味着重复使用最后一个匹配的模式,因此您不必再次输入它并冒险让两者发生分歧。
最后,模式中的\K
违背了匹配,“保留”左边的内容,以便它不会被替代品吞噬。
答案 1 :(得分:2)
cat file | sed -e ':l
0,/my_search_str/ {
/my_search_str/! {
N;
b l
}
s/my_search_str/replace_this/g
:t
N
b t
}
'
这对我有用: 档案:(之前)
hello1
my_search_str
hello2
mysearch_str
hello3
文件中:(后)
hello1
replace_this
hello2
mysearch_str
hello3
答案 2 :(得分:1)
我要做的是将所有行追加到一行并替换内容。
$ cat f
import java.io.File;
import java.io.File;
$ sed -n 'N
${
s/import java.io.File;/import java.io.IOException/
p
}' f
import java.io.IOException
import java.io.File;
工作原理:首先,我禁止行打印,这是默认行为,将-n
选项传递给sed。
然后是sed命令。第一个是N
命令:它将换行符和流的下一行附加到当前行,然后保持在模式空间。这会将当前行更改为下一行,然后将附加下一行...直到文件末尾。
在文件末尾以及在最后一行执行N
命令之后,模式空间将包含所有行。然后,在文件的末尾(由$
地址指定),我们只需用以下内容替换所需的行:
s/import java.io.File;/import java.io.IOException/
由于s///
命令默认情况下在模式空间中每次迭代只执行一次替换,因此它只会替换第一行。现在模式空间已替换了行,但由于我们使用了-n
选项,因此不会打印出来。因此,我们需要使用p
命令打印它。我们将在文件末尾执行两个操作后,使用$
对其进行处理,并将操作放在括号({}
)之间。
在那里,为了清楚起见,我们只是在多行中提供了sed命令。我们可以在一条线上使用它们;用分号分隔它们:
$ sed -n 'N;${s/import java.io.File;/import java.io.IOException/;p;}' f
import java.io.IOException
import java.io.File;
HTH
答案 3 :(得分:0)
您可以使用shell脚本(Bash)
#!/bin/bash
declare -i toggle=0
while read -r line
do
case "$line" in
*import*java.io.File*)
if [ $toggle -eq 1 ];then
echo "$line"
continue
fi
echo "import java.io.Exception";
toggle=1
continue
;;
esac
echo "$line"
done < file
示例输出
$> more file
import java.util.Scanner;
import java.io.File;
import java.io.File;
$> bash search_replace.sh
import java.util.Scanner;
import java.io.Exception
import java.io.File;
或者你可以将整个文件啜饮到内存中并进行一次替换
data=$(<file)
echo "${data/import java.io.File;/import java.io.IOException}"
答案 4 :(得分:0)
只需在命令行上执行,如下所示:
cat text.txt |
awk '/File/{
if ( count < 1 ){ gsub("File","IOException")}
count++
print
}'