-1

I've a file in which I want to delete the line which is matching with the entire string using sed.

Content of my file test.txt

test.pwd=test@123
test.pwd.path=/tmp/test
test.pwd1.sample=123

I've tried with the below sed command but it's deleting the line which is matching with that pattern

sed -i "s/test.pwd/d" test.txt

instead of deleting only line 1 it's deleting the first two lines

Ashok
  • 3,190
  • 15
  • 31
  • `sed -i "s/^test\.pwd=/d" test.txt` – Paul Pazderski Jul 26 '23 at 18:44
  • @PaulPazderski `test.pwd` is coming as a dynamic variable in that case how I can do that? – Ashok Jul 26 '23 at 18:46
  • `sed -i "s/^${tobedeleted}=/d" test.txt` could work if it is a shell script and setting a variable `tobedeleted`. In general your problem with matching to many lines can be fixed quite easily if you just also match the following `=`. – Paul Pazderski Jul 26 '23 at 18:47
  • Do you have to use `sed`? You can do this more easily with `grep -v` – Barmar Jul 26 '23 at 19:12
  • @PaulPazderski the above command is not working. getting an error unterminated s command – Ashok Jul 26 '23 at 19:14
  • @Barmar yeah I want to use sed. using grep -v I've done it. – Ashok Jul 26 '23 at 19:15
  • You shouldn't have `s` at the beginning. That's for replacing a string inside the line, `s/old/new/`. You should be getting an error from your code. – Barmar Jul 26 '23 at 19:16
  • When you use `sed` you need to escape special characters like `.`. This is a PITA if it's in a variable. – Barmar Jul 26 '23 at 19:17
  • @Barmar can you share the command – Ashok Jul 26 '23 at 19:23
  • See https://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed – Barmar Jul 26 '23 at 19:26
  • `grep -v "test.pwd" myfile.txt > tmpfile && mv tmpfile myfile.txt` @Barmar if i use this command it's deleting the line matching with that pattern but I want to delete only one line – Ashok Jul 26 '23 at 19:29
  • `grep -F -v "test.pwd=" myfile.txt`. `-F` makes it match literal characters instead of regular expression, and adding `=` prevents it from matching `test.pwd1` – Barmar Jul 26 '23 at 19:30
  • Note that `-F` can't anchor with `^`, so might also throw away `other.test.pwd=...` though that doesn't look like an issue here. – Paul Hodges Jul 26 '23 at 20:01

3 Answers3

2

If a non-sed answer is OK, here's perl that splits the line on = and tests the first part for inequality (avoiding regex)

pattern='test.pwd'
perl -F= -slane 'print if $F[0] ne $patt' -- -patt="$pattern" test.txt

If the output looks like what you want, add -i: perl -i -F= ...

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Why not just `"print if \$F[0] ne '$pattern'"` ? You've little enough perl that you can use the shell for substitution. – stevesliva Jul 27 '23 at 03:15
  • It's the principle of it. This is the perl analog to awk's -v option. What if pattern contains a single quote? (answer: `"print if \$F[0] ne '${pattern//\'/\\\'}'"`) – glenn jackman Jul 27 '23 at 14:06
  • 1
    Another technique is to use the environment to pass the data: `export pattern="..."` and then `'print if $F[0] ne $ENV{pattern}'` – glenn jackman Jul 27 '23 at 14:08
0

Remember that you are using regex metacharacters. sed -i "s/test.pwd/d" test.txt says "delete any line that has test, then any single character, then pwd". In your file, all of the lines you showed match.

Quote the ., and add something that disqualifies non-matching lines. As
Paul Pazderski suggested in his very first comment, adding the = does the trick, though more specificity is better. sed -i 's/^test[.]pwd=/d' test.txt will only remove the intended line from your example.

If putting your pattern in a variable, be wary of quoting and metacharacters that need backslashes, but for this example, it looks pretty straightforward.

$: cat file
safe-line=seeMe
test.pwd=test@123
test-pwd=keepMe
test.pwd.path=/tmp/test
test.pwd1.sample=123

$: pat="test.pwd" # loses most lines
$: sed "/$pat/d" file
safe-line=seeMe

$: pat="test.pwd=" # still loses test-pwd
$: sed "/$pat/d" file
safe-line=seeMe
test.pwd.path=/tmp/test
test.pwd1.sample=123

$: pat=^test\.pwd= # unquoted string, literal dot - still loses test-pwd 
$: sed "/$pat/d" file
safe-line=seeMe
test.pwd.path=/tmp/test
test.pwd1.sample=123

$: pat="^test\.pwd=" # works, but some may wonder - why not \\ ?
$: sed "/$pat/d" file
safe-line=seeMe
test-pwd=keepMe
test.pwd.path=/tmp/test
test.pwd1.sample=123

$: pat="^test[.]pwd=" # works, and clear
$: sed "/$pat/d" file
safe-line=seeMe
test-pwd=keepMe
test.pwd.path=/tmp/test
test.pwd1.sample=123


Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
0
cat test.txt
test.pwd=test@123
test.pwd.path=/tmp/test
test.pwd1.sample=123

Execute: grep -v "^test[.]pwd=" test.txt > test1.txt

cat test1.txt

test.pwd.path=/tmp/test
test.pwd1.sample=123
Raj
  • 13
  • 3
  • Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, **can you [edit] your answer to include an explanation of what you're doing** and why you believe it is the best approach? – Jeremy Caney Aug 04 '23 at 00:04