2

I'm attemping to make a script which will take the 1st positional argument in $foo and remove all the lines before the $foo line in files.txt. However I keep getting the following error: sed: -e expression #1, char 22: unknown command: f. My input is recup_dir.6/f5681240.mpg, I have even tried escaping the / by recup_dir.6\/f5681240.mpg but it didn't help. I also searched around for different methods of escaping text but non helped. My code is:

foo=$1;
sed -i "0,/^file $foo$/d" files.txt

EDIT: Making the question more clear, say I have a file named files.txt

file ab/c
file eg/f
file hi/j
file xy/z

Now I want to remove all elements before a specific element say hij, so I use the command sed -i '0,/^file hi\/j$/d' files.txt which works fine.

However when I try to use this as part of a script shown above it fails. Running ./script.sh eg\/f it fails with error sed: -e expression #1, char 23: unknown command: `f'

Thanks

8
  • Try: sed -i "0,#^file $foo$#d" files.txt. it's not necessary to use always / as the separator in sed. Commented Oct 6, 2022 at 9:02
  • @EdgarMagallon it gives me an error sed: -e expression #1, char 3: unexpected ','
    – DentFuse
    Commented Oct 6, 2022 at 9:07
  • It seems the problem is with the , after 0 character. I'm no sure if that's the correct syntax for sed. Commented Oct 6, 2022 at 9:11
  • @EdgarMagallon stackoverflow.com/a/17365103/5378459 this is the answer I was using to make the sed command
    – DentFuse
    Commented Oct 6, 2022 at 9:15
  • It's weird , I'm not rally sure what is happening. I will have to read more about sed :). Commented Oct 6, 2022 at 9:23

1 Answer 1

2

The issue is that your string contains a slash character. When injected by the shell into the sed expression, that character creates a syntax error (it ends the regular expression early).

One way to fix this is to ensure that every / is escaped as \/ in the string you inject, but this is a bit awkward. Another way is to use a delimiter that is not found in the string:

foo=$1
sed -i "1,\:^file $foo$:d" files.txt

Note that the first occurrence of the delimiter needs to be escaped in the expression and that 0 is not generally a valid start of a range.

If you also want to output the matching line:

foo=$1
sed -i "1,\:^file $foo$: { \:^file $foo$: p; d; }" files.txt

Alternative solution:

awk -v file="$foo" 'output; $0 == "file " file { output = 1 }' files.txt

This outputs each line if the variable output is not zero or blank. The variable is set to 1 whenever a line is file followed by the string given on the command line to the variable file.

If you also want to output the matching line:

awk -v file="$foo" '$0 == "file " file { output = 1 }; output' files.txt
2
  • Thanks! That works! Can you explain why this delimiter worked whereas sed -i "0,#^file $foo$#d" files.txt posted by Edgar above didn't?
    – DentFuse
    Commented Oct 6, 2022 at 9:33
  • @DentFuse The # was not \#.
    – Kusalananda
    Commented Oct 6, 2022 at 9:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .