0

I am trying to find the exact match of the pattern $i in C1.txt file and the remove the matching lines using sed command. But ended up with issue. Please find my findings and other details below.

C1.txt

# file: /home/mytest/data # owner: own # group: group-sm user::r-x group::rwx mask::rwx other::--- default:user::rwx default:group::r-x default:group:smr:rwx default:group:agm:r-x default:mask::rwx default:other::---
# file: /home/mytest/datasr123 # owner: own # group: group-sm user::r-x group::rwx mask::rwx other::--- 

Variable value

i=/home/mytest/data 

Code

#!/bin/bash
Input=C1.txt
  j=0
      while IFS= read -r line;
      do
      j=$((j+1))
        Exists=$(echo $line | grep -iwoP "$i" )
        if [[ ! -z "$Exists" ]]; then
        sed -i "$j /\b"$i"\b/d" "$Input"
        fi
      done <"$Input"

Expected Result

C1.txt

# file: /home/mytest/datasr123 # owner: own # group: group-sm user::r-x group::rwx mask::rwx other::---

Error Message

sed: -e expression #1, char 3: unknown command: `/'
  • I need to remove only the line which matches the exact pattern /home/mytest/data from the file C1.txt. Hope now it clarifies. – user393222 Feb 1 at 6:02
  • Both lines of your input match that pattern. – NickD Feb 1 at 23:12
1

The reason you get an error is because your search string contains / characters, which are confused with the marker characters. In other words, you are asking sed to do this:

sed "//home/mytest/datasr123/d"

which produces the error you saw. IOW, the pattern cannot contain the character that you use as a marker. If you know that your pattern does not contain a given character, you can use that character as a marker; e.g. since there is no ; in your search string, you could do this:

sed "\;/home/mytest/datasr123;d"

orr in terms of $i:

sed "\;$i;d"

See the man page of sed under Addresses for details on how to specify addresses.

Of course, whether this is useful depends on whether you know of a character that will never occur in your search strings: any character will do as a marker, but if your search string is input by the user, there are no guarantees that what you choose will not occur in the search string - you would have to scan it in order to find a character that does not occur in it.

And the easiest method is to not use sed at all, but fall back on grep (with thanks to @Kusalananda for fixing my bone-headed mistakes):

grep -v -F -e "$i" -- <file>

will show only the lines that do not match the pattern (that's the -v - the -F tells grep to interpret the string literally, not as a regexp, so that for example * and . are matched literally; the -e allows the pattern to start with a - and not be interpreted as an option to grep; and the -- allows the filename to start with a - and not be interpreted as an option to grep; the last two are always good to have in a grep invocation inside a script, since you never know when that situation may arise, although we mostly get away with it when grep is called interactively).

BUT N.B.: The question has been edited and the change in the pattern has invalidated every method in this answer completely. The pattern matches both lines in the input, so both of them will be deleted. You would have to reinterpret the pattern somehow, e.g. look not for "$i" since this will match both; instead look for "${i} " where the additional space will match the first line but not the second, or "${i}s" to match the second line but not the first. Note also that with -F, you cannot use character classes (so \b is out).

| improve this answer | |
0

The original grep -iwoPdoes not seem to reflect the idea of an "exact match".... however

To delete complete lines exactly matching the search string then it needs anchoring at the beginning ^ and end $ of the line.

sed "\|^$i$|d" C1.txt
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.