如何使用sed或awk命令替换文本文件中首行以Li开头的行内指定位置的字符串
如何用sed或awk修改科研输入文件的指定列?
我有一个给科研工具用的输入文本文件,内容如下:
# # Keywords: # LiFePO4 end name Li5FeO4 cell 18.557309 18.316802 9.125725 90.047539 90.100646 90.060551 0 0 0 0 0 0 fractional 1 Li core 0.06001 0.059408 0.849507 1 1 0 0 0 0 Li1 core 0.025416 0.339078 0.128746 1 1 0 0 0 0 Li2 core 0.02517 0.838929 0.130747 1 1 0 0 0 0 Li3 core 0.525498 0.339179 0.127632 1 1 0 0 0 0 Li4 core 0.524753 0.841333 0.129329 1 1 0 0 0 0 Li5 core 0.179907 0.158182 0.634012 1 1 0 0 0 0 Li6 core 0.180817 0.666028 0.628327 1 1 0 0 0 0
我的需求是:仅修改第一行以Li开头(不带数字后缀)的行,把该行末尾四个0中的第二个0(也就是倒数第三列的0)替换成1,修改后目标内容如下:
# # Keywords: # LiFePO4 end name Li5FeO4 cell 18.557309 18.316802 9.125725 90.047539 90.100646 90.060551 0 0 0 0 0 0 fractional 1 Li core 0.06001 0.059408 0.849507 1 1 0 1 0 0 Li1 core 0.025416 0.339078 0.128746 1 1 0 0 0 0 Li2 core 0.02517 0.838929 0.130747 1 1 0 0 0 0 Li3 core 0.525498 0.339179 0.127632 1 1 0 0 0 0 Li4 core 0.524753 0.841333 0.129329 1 1 0 0 0 0 Li5 core 0.179907 0.158182 0.634012 1 1 0 0 0 0 Li6 core 0.180817 0.666028 0.628327 1 1 0 0 0 0
我尝试了下面的sed命令,但没能成功实现需求:
sed -E "s/^(([^ ]+ +){3})0 /\1 /" file1
有没有可行的sed或awk命令能完成这个修改?
解决方案
方法1:使用sed命令
这个需求的关键是精准匹配**仅第一行Li开头(后面没有数字)**的行,然后定位到倒数第三列的0替换为1。可以用下面的sed命令:
sed -E '/^Li / s/(( [0-9]+){2}) 0( [0-9]+){2}$/\1 1\3/' input.txt
命令解释:
/^Li /:先过滤出以Li(注意后面有空格)开头的行,这样就不会匹配到Li1、Li2这类带数字后缀的行;s/(( [0-9]+){2}) 0( [0-9]+){2}$/\1 1\3/:(( [0-9]+){2}):匹配倒数第四、第三列(也就是目标行里的1 1部分);0:精准匹配倒数第二列的0;( [0-9]+){2}$:匹配最后两列的0 0;- 替换时把中间的
0改成1,其他原有内容保留。
如果要直接修改原文件(原地编辑),可以加-i参数:
sed -i -E '/^Li / s/(( [0-9]+){2}) 0( [0-9]+){2}$/\1 1\3/' input.txt
方法2:使用awk命令
awk处理列操作更直观,适合这种需要精准定位列的场景:
awk '/^Li / { $9 = 1 } 1' input.txt
命令解释:
/^Li /:匹配以Li开头的目标行;$9 = 1:把第9列(数一下目标行的列:Li是第1列,core第2,坐标占3-5列,然后1、1、0是6-8列,倒数第三列正好是第9列)的值改成1;1:表示打印所有行(包括修改后的目标行和未修改的其他行)。
如果需要原地编辑文件,可以用临时文件中转:
awk '/^Li / { $9 = 1 } 1' input.txt > temp.txt && mv temp.txt input.txt
内容的提问来源于stack exchange,提问作者Happy Coder
相关产品推荐
相关产品推荐

