开发者

Linux SED script find the 1st line that match pattern and delete it

I want to create a sed command to find in a file the 1st line that matchs a pattern and the delete all that line or replace it all with some other text. I dont want to match all the line because the rule is to match part of it.

how can 开发者_如何学Ci do it with sed?

for instance:

myline 1 is pretty
line 2 is ugly
myline 111 is nice

I want to delete the first line that contains "1 is"

UPDATE: My line may have characters like "/" and "<"

Regards Fak


From the sed FAQ:

sed '0,/RE/{//d;}' file        # delete only the first match
sed '0,/RE/s//to_that/' file   # change only the first match

If you are not using GNU sed, then check out the alternatives in the FAQ.


I tend to use awk for more complicated tasks, it's a bit more powerful than sed, having proper looping and selection constructs (expanded for readability, you can compress it back to one line if you wish):

pax$ echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk '
     /1 is/ {if (f) {print} else {f = 1}}
    !/1 is/ {print}'

xyz
line 2 is ugly
myline 111 is nice

For any line not matching the pattern (!/1 is/), it just prints it.

For lines that do match the pattern, it prints them all if the flag f is set (it's initially not set). When the flags not set and it encounters a matching line, it sets the flag and doesn't print it. This basically deletes the first matching line as desired.

If you want to modify the first matching line rather than deleting it, you just insert code alongside the f = 1 to do that, something like:

pax$ echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk '
     /1 is/ {if (f) {print} else {f = 1;print "URK!!!"}}
    !/1 is/ {print}'

xyz
URK!!!
line 2 is ugly
myline 111 is nice

To use a shell variable in awk, you can use the -v option to pass it in as a real awk variable:

pax$ export xyzvar=URK ; echo '
xyz
myline 1 is pretty
line 2 is ugly
myline 111 is nice'  | awk -vmyvar=$xyzvar '
     /1 is/ {if (f) {print} else {f = 1;print myvar}}
    !/1 is/ {print}'

xyz
URK
line 2 is ugly
myline 111 is nice


You can accomplish it without sed. Bash script:

LINE=$(grep -n "$EXPR" "$FILE" |head -1 |cut -f1 -d:)
head -$(expr $LINE - 1 ) $FILE
tail +$(expr $LINE + 1 ) $FILE

Just declare $EXPR and $FILE.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜