0

I need to check if a file contains a specific two strings and if it does, remove all the text between them (strings included). Let's say I have a file text which looks something like this:

line of text
line of text
line of text
line of text
#1st string
line of text
line of text
line of text
#2nd string

Now I would like to delete all the lines between #1st string and #2nd string and those two strings included.

I tried getting the whole text into a variable and then removing them like that:

prefix="#1st string"
suffix="#2nd string"

#content of a file into variable
tempfile=$( cat text )
tempfile=${tempfile#"$prefix"}
tempfile=${tempfile%"$suffix"}
echo ${tempfile}

Unfortunately, this doesn't work because the text file contains some commands which somehow list the content of the current directory and blend the output into the variable which leaves the file corrupted. Can I prevent that somehow, or is there a better way of achieving this altogether?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
aMJay
  • 2,215
  • 6
  • 22
  • 34
  • 2
    As an aside, the reason why you see the contents if you directory is likely because your file contains a `*` wildcard character, and the unquoted expansion results in it being expanded to all filenames in the current directory. – Benjamin W. Jan 09 '21 at 01:23
  • Yes I can confirm that to be the case – aMJay Jan 09 '21 at 01:26
  • Following up BenjaminW's comment: variable references should almost always be double-quoted. See ["I just assigned a variable, but echo $variable shows something else"](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) and ["When is double-quoting necessary?"](https://unix.stackexchange.com/questions/68694/when-is-double-quoting-necessary) – Gordon Davisson Jan 09 '21 at 01:27

2 Answers2

4

You could use sed to remove the line range:

sed '/#1st string/,/#2nd string/d' text

To store the result in-place, use

sed -i '/#1st string/,/#2nd string/d' text

or the more portable

sed '/#1st string/,/#2nd string/d' text > tempfile && mv tempfile text

And finally, because you might have files where only the first string exists, you have to check existence of the second string first:

grep -q '#2nd string' text && sed '/#1st string/,/#2nd string/d' text
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
2

You could use grep's before and after feature:

prefix="#1st string"
suffix="#2nd string"

grep -B 100000000 $prefix text | grep -v $prefix > output
grep -A 100000000 $suffix text | grep -v $suffix >> output
Christian Fritz
  • 20,641
  • 3
  • 42
  • 71