1

I have been looking into sed and awk. I have not found an example that shows using a text file (findtext.txt) to scan all *.php files and remove the text.

pretty much I have a block of text that needed to be removed for a bunch of php files.

I know how to use the basic sed command like this

sed -i 's/sometext/replacetext/g' *.php

What i would like to do is have sed look in findtext.txt grab the block of text and then scan *.php and removed that block of text from the files.

acctman
  • 4,229
  • 30
  • 98
  • 142
  • 1
    Edit your question to show concise, testable sample input and expected output. You will get out of the answer to your question however much you put into asking it. – Ed Morton Feb 23 '16 at 02:06
  • You can create `findtext.txt` that contains your sed script such as `s/sometext/replacetext/g` to replace sometext with replacetext. You can put as much `sed` script as you need including deleting specific lines like `1d`, or `/sometext/,/anothertext/d`. Then use the script like `sed -i -f findtext.txt *.php`. – alvits Feb 23 '16 at 02:09
  • and if you mean 'remove malware code inserted into my website' then you can start crying now (sorry). You can search here for solutions, but they are very brittle. Good luck. – shellter Feb 23 '16 at 02:10

2 Answers2

3

There are two challenges:

  • Using text stored in a variable or file that should be treated literally when used as the regex argument to sed's s/// function presents the challenge of having to escape regex metacharacters in that text.

  • Additionally, since you're talking about a block of text that's stored in file findtext.txt, I assume you're talking about a multi-line solution - whereas sed is single line-oriented by default.

The following solution addresses both challenges:

# Read the multiline search string into a variable 
# and quote it to ensure literal treatment when used as a regex.
sometextQuoted=$(sed -e 's/[^^]/[&]/g; s/\^/\\^/g; $!a\'$'\n''\\n' < 'findtext.txt' | 
  tr -d '\n')

# Now process the *.php files:
# Read each file *as a whole* before performing the string replacement.
sed ':a; $!{N;ba}; s/'"$sometextQuoted"'/replacetext/g' *.php
  • The solution is based on this answer of mine, wich explains the sed command used to quote (escape) the search text (sometextQuoted=...) in detail.

  • ':a; $!{N;ba} is a standard sed idiom that reads an entire file at once.

  • Note how "$sometextQuoted" is spliced into the otherwise single-quoted sed script to avoid confusion over what the shell interprets up front vs. what sed ends up seeing.

  • Note that if you also wanted to read the replacement text (replacetext in your example) from a variable/file, a different form of quoting (escaping) would be required - again, see the linked answer.

Note: The 2nd sed command requires GNU sed, which I assume you're using (-i without an argument doesn't work with BSD/OSX sed); it is possible, but more complex, to make this work with BSD/OSX sed.
Also, I've omitted -i from the command so you can check the results first without replacing the original files.

Community
  • 1
  • 1
mklement0
  • 382,024
  • 64
  • 607
  • 775
1

Assign the content of findtext.txt to a bash variable, and use that variable in sed substitution. Below is a one line solution. I am not sure if it works if there are more than one line in findtext.txt.

$ findtext=$(cat findtext.txt) && sed -i.bak -e "s/$findtext/bbbb/g" *.php
alijandro
  • 11,627
  • 2
  • 58
  • 74
  • 1
    This will not solve the stated problem of " have a block of text that needed to be removed ", assuming that a "block of text" has multiple lines (a safe assumption in my book). Good luck to all. – shellter Feb 23 '16 at 03:18