在文件file.txt的第二行到最后一行中,我必须将“模式”替换为“字符串”。下面三个sed命令可以打印第二行到最后一行.但我需要将“模式”替换为“字符串”。有什么帮助吗?
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.用“胡萝卜”代替整条线,不管它含有什么
发布于 2016-07-28 17:21:09
在第二行到最后一行中将Sweet更改为Green,但前提是该行包含Sweet pepper
$ sed 'x; ${/Sweet pepper/s/Sweet/Green/;p;x}; 1d' file.txt
cabbage
spinach
collard greens
corn salad
Green pepper
kale
把第二行到最后一行的全部替换成胡萝卜,不管它包含什么内容:
$ sed 'x; ${s/.*/carrots/;p;x}; 1d' file.txt
cabbage
spinach
collard greens
corn salad
carrots
kale
它是如何工作的
让我们使用这个命令,一步一步地检查它:
sed 'x; ${s/.*/carrots/;p;x}; 1d'
x
这将交换模式空间(其中包含最近读取的行)和保持空间。
完成此操作后,持有空间将包含最近读取的行,模式空间将包含前一行。(例外情况是我们刚刚读了第一行。在这种情况下,持有空间将有第一行,模式空间将为空。)${s/.*/carrots/;p;x}
当我们在最后一行(由$
指示)时,模式空间包含第二行到最后一行,我们可以执行任何我们喜欢的替换或其他命令。完成后,我们使用p
打印第二行到最后一行。最后,我们交换模式并再次使用x
保存空间,以便模式空间再次包含最后一行。sed
会打印这一点,因为在默认情况下,在命令的末尾,sed
会打印模式空间中的任何内容。1d
当我们在第一行(由1
指示)时,patten空间是空的(因为没有前面的行)并删除它(d
)。一种更简单的方法
这种方法很容易理解,但代价是执行速度较慢:
$ tac file.txt | sed '2 {/Sweet pepper/s/Sweet/Green/}' | tac
cabbage
spinach
collard greens
corn salad
Green pepper
kale
对于胡萝卜来说:
$ tac file.txt | sed '2 s/.*/carrots/' | tac
cabbage
spinach
collard greens
corn salad
carrots
kale
它是如何工作的:这里的,我们使用tac
来反转行的顺序。观察:
$ tac file.txt
kale
Sweet pepper
corn salad
collard greens
spinach
cabbage
这样,第二行到最后一行就变成了第2行。因此,我们只是简单地告诉sed在2号线上操作。然后,我们再次使用tac
来放置行,但顺序正确。
发布于 2016-07-28 17:28:47
您可能会发现awk脚本更容易理解、维护、移植等:
$ 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
的方法
$ awk 'NR==FNR{tgt=NR-3;next} (FNR==tgt) { $0="carrots" } 1' file file
cabbage
spinach
carrots
corn salad
Sweet pepper
kale
发布于 2016-07-28 18:28:16
awk解决方案
$ 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解决方案
$ 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
https://stackoverflow.com/questions/38649053
复制相似问题