首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >替换文件第二行到最后一行的“模式”

替换文件第二行到最后一行的“模式”
EN

Stack Overflow用户
提问于 2016-07-29 01:14:25
回答 3查看 5.9K关注 0票数 6

在文件file.txt的第二行到最后一行中,我必须将“模式”替换为“字符串”。下面三个sed命令可以打印第二行到最后一行.但我需要将“模式”替换为“字符串”。有什么帮助吗?

代码语言:javascript
代码运行次数:0
运行
复制
sed -e '$!{h;d;}' -e x file.txt

sed -n 'x;$p' file.txt

sed 'x;$!d' file.txt

$ cat file.txt  
cabbage  
spinach  
collard greens  
corn salad  
Sweet pepper  
kale  

如何替换文件的第二行到最后一行(甜椒):

如果第二行至最后一行包含“甜椒”,则将“甜椒”改为“绿色”。

b.用“胡萝卜”代替整条线,不管它含有什么

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-07-29 01:21:09

在第二行到最后一行中将Sweet更改为Green,但前提是该行包含Sweet pepper

代码语言:javascript
代码运行次数:0
运行
复制
$ sed 'x; ${/Sweet pepper/s/Sweet/Green/;p;x}; 1d' file.txt
cabbage
spinach
collard greens
corn salad
Green pepper
kale

把第二行到最后一行的全部替换成胡萝卜,不管它包含什么内容:

代码语言:javascript
代码运行次数:0
运行
复制
$ sed 'x; ${s/.*/carrots/;p;x}; 1d' file.txt
cabbage
spinach
collard greens
corn salad
carrots
kale

它是如何工作的

让我们使用这个命令,一步一步地检查它:

代码语言:javascript
代码运行次数:0
运行
复制
sed 'x; ${s/.*/carrots/;p;x}; 1d'
  • x 这将交换模式空间(其中包含最近读取的行)和保持空间。 完成此操作后,持有空间将包含最近读取的行,模式空间将包含前一行。(例外情况是我们刚刚读了第一行。在这种情况下,持有空间将有第一行,模式空间将为空。)
  • ${s/.*/carrots/;p;x} 当我们在最后一行(由$指示)时,模式空间包含第二行到最后一行,我们可以执行任何我们喜欢的替换或其他命令。完成后,我们使用p打印第二行到最后一行。最后,我们交换模式并再次使用x保存空间,以便模式空间再次包含最后一行。sed会打印这一点,因为在默认情况下,在命令的末尾,sed会打印模式空间中的任何内容。
  • 1d 当我们在第一行(由1指示)时,patten空间是空的(因为没有前面的行)并删除它(d)。

一种更简单的方法

这种方法很容易理解,但代价是执行速度较慢:

代码语言:javascript
代码运行次数:0
运行
复制
$ tac file.txt | sed '2 {/Sweet pepper/s/Sweet/Green/}' | tac
cabbage
spinach
collard greens
corn salad
Green pepper
kale

对于胡萝卜来说:

代码语言:javascript
代码运行次数:0
运行
复制
$ tac file.txt | sed '2 s/.*/carrots/' | tac
cabbage
spinach
collard greens
corn salad
carrots
kale

它是如何工作的:这里的,我们使用tac来反转行的顺序。观察:

代码语言:javascript
代码运行次数:0
运行
复制
$ tac file.txt
kale
Sweet pepper
corn salad
collard greens
spinach
cabbage

这样,第二行到最后一行就变成了第2行。因此,我们只是简单地告诉sed在2号线上操作。然后,我们再次使用tac来放置行,但顺序正确。

票数 13
EN

Stack Overflow用户

发布于 2016-07-29 01:28:47

您可能会发现awk脚本更容易理解、维护、移植等:

代码语言:javascript
代码运行次数:0
运行
复制
$ awk 'NR==FNR{tgt=NR-1;next} (FNR==tgt) && /Sweet pepper/ { $1="green" } 1' file file
cabbage
spinach
collard greens
corn salad
green pepper
kale

$ awk 'NR==FNR{tgt=NR-1;next} (FNR==tgt) { $0="carrots" } 1' file file
cabbage
spinach
collard greens
corn salad
carrots
kale

要在结束之前更改第3行,而不是在结束前更改第1行?这只是简单而明显的将-1更改为-3的方法

代码语言:javascript
代码运行次数:0
运行
复制
$ awk 'NR==FNR{tgt=NR-3;next} (FNR==tgt) { $0="carrots" } 1' file file
cabbage
spinach
carrots
corn salad
Sweet pepper
kale
票数 2
EN

Stack Overflow用户

发布于 2016-07-29 02:28:16

awk解决方案

代码语言:javascript
代码运行次数:0
运行
复制
$ cat 38649053
cabbage
spinach
collard greens
corn salad
Sweet pepper
kale
$tac 38649053 | awk 'NR==2{if($0=="Sweet pepper")#is record sweet pepper?
{ 
$1="green"} #changing sweet to green , note $1 is the first field
else{
$0="carrot" # $0 is the whole record which replaced by carrot
}}
{record[NR]=$0} #adding each record to an record number-indexed array
END{ #printing the records in reverse at the end
i=NR;for(;i>=1;i--)print record[i]} 
'
cabbage
spinach
collard greens
corn salad
green pepper
kale

Sed解决方案

代码语言:javascript
代码运行次数:0
运行
复制
$ cat 38649053
cabbage
spinach
collard greens
corn salad
Sweet pepper
kale 
$ lines=$(wc -l <38649053) # lines contains the total # of lines
$ ((s2l=--lines)) # storing the second to last line number to s2l
$ sed -E "${s2l}"'{/^Sweet pepper$/!s/.*/carrot/;/^Sweet pepper$/s/Sweet/green/}' 38649053
# applying the sed to the required line
cabbage
spinach
collard greens
corn salad
green pepper
kale 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38649053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档