1

I'm trying to run a bash script that removes lines from a file with only the specific string I pass to it, "/home/ken/sed.txt".

Current script which does nothing:

#!/bin/bash

script="\\/home\\/ken\\/sed.txt"

sed -i "/\<$script\>/d" /home/ken/sed.txt

This deletes all rows:

#!/bin/bash

script="\\/home\\/ken\\/sed.txt"

sed -i "/$script/d" /home/ken/sed.txt

The file:

1 1 1 1 1 /home/ken/sed.txt
6 6 6 6 6 /home/ken/sed.txt
2 2 2 2 2 /home/ken/sed.txt
6 6 6 6 6 /home/ken/sed.txt
3 3 3 3 3 /home/ken/sed.txt
3 3 3 3 3 /home/ken/sed.txt
5 5 5 5 5 /home/ken/sed.txt
1 1 1 1 1 a/home/ken/sed.txt
6 6 6 6 6 a/home/ken/sed.txt
2 2 2 2 2 a/home/ken/sed.txt
6 6 6 6 6 a/home/ken/sed.txt
3 3 3 3 3 a/home/ken/sed.txt
3 3 3 3 3 a/home/ken/sed.txt
5 5 5 5 5 a/home/ken/sed.txt

Desired outcome:

1 1 1 1 1 a/home/ken/sed.txt
6 6 6 6 6 a/home/ken/sed.txt
2 2 2 2 2 a/home/ken/sed.txt
6 6 6 6 6 a/home/ken/sed.txt
3 3 3 3 3 a/home/ken/sed.txt
3 3 3 3 3 a/home/ken/sed.txt
5 5 5 5 5 a/home/ken/sed.txt

Any assistance would be greatly appreciated.

3 Answers3

4
script='/home/ken/sed.txt'
sed -n "\|\b$script|p" file

Output:

1 1 1 1 1 a/home/ken/sed.txt
6 6 6 6 6 a/home/ken/sed.txt
2 2 2 2 2 a/home/ken/sed.txt
6 6 6 6 6 a/home/ken/sed.txt
3 3 3 3 3 a/home/ken/sed.txt
3 3 3 3 3 a/home/ken/sed.txt
5 5 5 5 5 a/home/ken/sed.txt

I switched from //p to \||p to avoid escaping /.

From man sed:

\cregexpc: Match lines matching the regular expression regexp. The c may be any character.

See: \b

Cyrus
  • 84,225
  • 14
  • 89
  • 153
  • This "works" in that it creates a new file with the desired outcome - I'd like it to edit the current file. Replacing -n with -ni or just -i doesn't work still – soulkingbrook Mar 25 '20 at 18:41
  • 1
    With GNU sed: If you want to edit your file "in place" add option `-i`. With non GNU sed try `-i ''`. – Cyrus Mar 25 '20 at 18:42
  • -i doesn't work. It appends the "desired output" to the end of sed.txt edit: wait, hold on. – soulkingbrook Mar 25 '20 at 18:47
  • Cancel that - looks like the order of the options is important. The correct way is -ni. I had -in. So: ```sed -ni "\|\b$script|p" /home/ken/sed.txt``` Thank you! – soulkingbrook Mar 25 '20 at 18:53
  • 1
    @soulkingbrook `-in` will uses `n` as the backup extension. Look for a `/home/ken/sed.txtn` file. – Shawn Mar 25 '20 at 18:59
1

As usual when wanting to edit a file in place, I recommend ed over sed -i:

#!/bin/sh
script=" /home/ken/sed.txt"
ed -s sed.txt <<EOF
g!$script!d
w
EOF

Note the addition of a space in your $script variable, to avoid matching the a/home/ken/sed.txt lines. Without that, every line in your example file is deleted, as you've seen.

Shawn
  • 47,241
  • 3
  • 26
  • 60
0

Why is sed needed? I think you could just grep with the "--fixed-strings" and the "--invert-match" option:

$ fgrep -v ' /home/ken/sed.txt' file.txt
1 1 1 1 1 a/home/ken/sed.txt
6 6 6 6 6 a/home/ken/sed.txt
2 2 2 2 2 a/home/ken/sed.txt
6 6 6 6 6 a/home/ken/sed.txt
3 3 3 3 3 a/home/ken/sed.txt
3 3 3 3 3 a/home/ken/sed.txt
5 5 5 5 5 a/home/ken/sed.txt

grep -F -v ' /home/ken/sed.txt' file.txt
leogtzr
  • 480
  • 4
  • 7