Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

When using grep in conjunction with sed, everything is ok as long as the standard forward slash delimiters are used.

find . -maxdepth 2 -xdev -type f -exec grep -i "teststring" -l {} \; -exec sed -i '/./d' {} \;

If I change this to another character like "+" or "#", it doesn't work (I need to change this because the teststring may contain the "/" character and cause an error.

find . -maxdepth 2 -xdev -type f -exec grep -i "teststring" -l {} \; -exec sed -i '#.#d' {} \;

Is there away around this problem?

Hang on. Why are you using grep AND sed? Tell us what you're trying to do as, whatever it is, there IS a better way! – Ed Morton Dec 13, 2012 at 18:00 Find all files with teststring present and (with several variations) delete contents of file/delete line/or delete string. – user1166981 Dec 13, 2012 at 18:07

You need to backslash the first delimiter

The BSD man page that is sometimes used for sed (e.g., OSX) doesn't make it clear, but using an arbitrary delimiter for the sed regular expression address only works if the RE is preceded by a backslash.

\xMATCHTHISxd

This will delete lines that have MATCHTHIS somewhere.

This has nothing to do with not playing nice with if you really can't change the delimiter then just escaped all instances of / with a backslash \ like:

sed -i '/\//d'

but sed -i '\#/#d' so do the trick, this will delete all lines that contain a /.

You should tell us what you are trying to do because I have a feeling the is not needed at all here.

According to sed's man page, any character may be used as a line matching regular expression with the syntax \cregexpc where c is any character.

find . -maxdepth 2 -xdev -type f -exec grep -i "teststring" -l {} \; -exec sed -i '\#.#d' {} \;

If you want to use a different delimiter in the sed delete command, you need to start the address with a backslash, like this:

sed -i '\#.#d'
                If the usage is like: 's\#searchstring#replacementstring#gI' I get an error: unterminated 's' command. if the normal delimiters are there I get no error. Any idea why?
– user1166981
                Dec 13, 2012 at 18:00
                you don't need the backslash when doing search and replace i.e. s#searchstring#replacementstring#g will work.
– dogbane
                Dec 13, 2012 at 18:05

It looks like you're trying to empty any files that contain teststring. That'd simply be:

find . -maxdepth 2 -xdev -type f | 
while IFS= read -r file; do
   if grep -i "teststring" -q "$file"; then
      > "$file"

If you want to just delete those lines that contain at least one character then that'd be:

find . -maxdepth 2 -xdev -type f | 
while IFS= read -r file; do
   if grep -i "teststring" -q "$file"; then
      sed -i '/^./d' "$file"

If you want to delete those lines that contain some string "foo" then that'd be:

find . -maxdepth 2 -xdev -type f | 
while IFS= read -r file; do
   if grep -i "teststring" -q "$file"; then
      sed -i '/foo/d' "$file"

Just follow that pattern and whatever you want to do is trivial, assuming you don't have file names that contain newlines. You could move the grep into the find line if you like, but it seems kinda pointless and obfuscates the code.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.