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
.
精彩评论