I was doing a basic shell script and got a datafile that I need to edit a bit to work with it. The thing is it has multiple lines repeated and even words, so I wanted to fast-edit with vim's substitution commands or just a sed. The thing is I did not achieve to match the path I want to substitute to 'nothing' basically.

The actual file is bigger, I'll paste just a part of it but think it has lots of lines like this:


So the thing is, I want to delete the ">category.php part as I don't need it hence, I got myself to this regex:

\">[A-z]+\.php[ ]+ // So in case it has some spaces, I add the that character class with basically a space. I also escaped the first double quote just in case it makes some trouble but with no success, neither vim nor sed deletes that part.

The actual commands I ran were:

sed "s/\">[A-z]+.php//g" and :%s/\">[A-z]+.php//g in vim.

  • Does this answer your question? sed a pattern followed with any single character one or more times
    – muru
    Dec 28, 2022 at 20:09
  • 1
    You are obviously trying to parse some XML-like file. This is best done with an XML parser, such as xmlstarlet. Could you reformulate your question in terms of deleting parts of XML depending on the values of attributes in tags, and show a larger portion of the document, please?
    – Kusalananda
    Dec 29, 2022 at 7:08

4 Answers 4


Use cut command with " as delimiter:

cut -d\" -f1 input-file

You've made a couple of mistakes with your regex both in sed as well as vim. Others have given some good alternatives but I'd like to address why the commands you've given didn't work and how you could fix them.


Your command: sed "s/\">[A-z]+.php//g"

Firstly, your character class should have a valid end, in this case you probably meant to write [a-zA-Z].

Secondly, the + operator is a feature of extended regular expressions (ERE), these are not enabled by default. To enable it, use the and the -E/-r/--regexp-extended flag.

You could either do that or you could prefix the operator with a backslash like \+.

Corrected command: sed 's/\">[a-zA-Z]\+.php//g'


Your command: :%s/\">[A-z]+.php//g

Again, your character class is wrong. It should be [a-zA-Z] though this might not matter if your search is case insensitive.

According to the vim manual, the + operator should also be prefixed with a backslash in order to work as you intend it to.

Corrected command: :%s/\">[a-zA-Z]\+.php//g


  • In sed, if you use ERE, you could use \w instead of [a-zA-Z]
  • In vim, you could use \a instead of [a-zA-Z]

You may not need to dig in regex, sample awk script can do the work:

awk -F\" '{print $1}' input_file

use " as delimiter and print only first token.


Assuming you are working with some XML document like

<?xml version="1.0"?>
  <node attr="Category.php">category.php</node>
  <node attr="Copyright.php">Copyright.php</node>
  <node attr="Core.php">Core.php</node>
  <node attr="Credit.php">Credit.php</node>

... and assuming you want to delete the value of any node node that has an attr attribute with value Category.php. You may do this using xmlstarlet like so:

xmlstarlet edit --update '//node[@attr="Category.php"]' --value '' file.xml

or, using shorter syntax,

xmlstarlet ed -u '//node[@attr="Category.php"]' -v '' file.xml

The string //node[@attr="Category.php"] is an XPath query that matches the set of node nodes anywhere in the document, with an attribute attr of value Category.php.

This would generate

<?xml version="1.0"?>
  <node attr="Category.php"/>
  <node attr="Copyright.php">Copyright.php</node>
  <node attr="Core.php">Core.php</node>
  <node attr="Credit.php">Credit.php</node>

From within the Vim editor, you would use

:%!xmlstarlet ed -u '//node[@attr="Category.php"]' -v ''

If you want to delete the whole matching node (not just its value), use

xmlstarlet edit --delete '//node[@attr="Category.php"]'


xmlstarlet ed -d '//node[@attr="Category.php"]'

instead of the xmlstarlet command above.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .