PseudoPsyche
PseudoPsyche

Reputation: 4592

Delete multi-line pattern starting on first line of file only

From a Bash script, I'm trying to delete a pattern from a file like the following:

<%
delete this tag
%><? keep this tag ?>
<% keep this tag %>

But only if that tag is at the beginning of the file, so the following would be untouched:

text to keep
<%
don't delete me now
%>

I've tried to piece something together from answers on other questions, but haven't been able to come up with a command that will work like this.

Is this possible with sed? Is there a different tool that would work better?

Upvotes: 0

Views: 84

Answers (4)

PseudoPsyche
PseudoPsyche

Reputation: 4592

So after posting, I figured out how to do this in sed with the following command:

sed -e '/<%/{1!b;:x;$!N;/%>/!bx;s/<%.*%>//}' -i "file"

An explanation of the command:

sed -e
    '/<%/           # When we match the start pattern, '<%', execute the following command block
    {
        1!b;        # If we're not on the first line when we match the start pattern, exit
        :x;         # Define label 'x'
        $!N;        # If not at the end of file, capture the current line
        /%>/!bx;    # If we're not at the end pattern, '%>', go to label 'x'
        s/<%.*%>//  # After reaching the end pattern, replace all matching text in the captured lines with nothing
    }'
    -i "file"

Upvotes: 0

anubhava
anubhava

Reputation: 785128

If you want to give perl a chance then this should work:

perl -0777 -pe 's/^\s*<%.*?%>//s' file

<? keep this tag ?>
<% keep this tag %>

Breakup:

  • -0777 : slurp mode to match all the file text including newlines
  • ^\s*: Match start followed by 0 or more white-spaces
  • <%.*?%>: Match your tag (lazy)

To save changes back to file:

perl -i -0777 -pe 's/^\s*<%.*?%>//s' file

Upvotes: 3

James Brown
James Brown

Reputation: 37404

Using awk:

$ awk '
NR==1 && /</ { d=1 }     # if < on the first line raise the del flag
d==1 {                   # if del flag up
    if(/>/)              # lower del flag at >
        d=0              
    sub(/<?[^>]+>?/,"")  # replace from < to > with nuthin
} 
/./                      # print nonempty lines
' file
<? keep this tag ?>
<% keep this tag %>

The other file processed:

text to keep
<%
don't delete me now
%>

Upvotes: 1

Matteo Baldi
Matteo Baldi

Reputation: 5828

You should use sed, like:

sed '0,/REGEXP/' your_input_file

where REGEXP is your desired regular expression.

Upvotes: 0

Related Questions