0

I'm trying to build a script that deletes some lines from a txt file after evaluating if the line is ok or needs to be removed.

The sed command evaluates to something like this:

sed -i '4d' file.txt

Everything is fixed except for the number of the line which can change, the command inside the script literally looks like this:

sed -i \'$lineNum\' $file

But it fails with error:

sed: -e expression #1, char 1: unknown command: `''

However if I run the same command on the command line, it works as expected.

Edit:

Removed sh tag since I'm actually using ksh, the editor I'm using is vi

I'm running on:

Distributor ID: RedHatEnterpriseServer
Description:    Red Hat Enterprise Linux Server release 6.4 (Santiago)
Release:        6.4
Codename:       Santiago
Artemio Ramirez
  • 1,116
  • 1
  • 10
  • 23
  • Are you using OS X? – Barmar Apr 06 '18 at 17:09
  • You have both [tag:bash] and [tag:ksh]. Which are you using? – Barmar Apr 06 '18 at 17:10
  • What text editor do you use? Is that a plain single quote or some other character? What does `od -c scriptfile` show? – glenn jackman Apr 06 '18 at 17:10
  • If you're using a Mac, see https://stackoverflow.com/questions/4247068/sed-command-failing-on-mac-but-works-on-linux – Barmar Apr 06 '18 at 17:11
  • "evaluates to something like"? The details are critical. Unless you ran `bash -x yourscript` and the *interpreter itself told you* that that was the result of the expansion, we need a [mcve] -- code you *actually tested* to produce the bug, precisely as given. – Charles Duffy Apr 06 '18 at 17:13
  • I suspect that you're expanding a variable with literal quotes. For that, we have lots of Q&A entries already in our knowledgebase; see in particular [BashFAQ #50](http://mywiki.wooledge.org/BashFAQ/050). Actually, given your error message, that suspicion is pretty much a matter of certainty. – Charles Duffy Apr 06 '18 at 17:13
  • ...by the way -- **please read the comments on the accepted answer to the linked question, describing why it's a dangerous idea**. I strongly, *strongly* suggest following [my answer](https://stackoverflow.com/a/32280085/14122) (or the advice given in the above-linked FAQ) instead. – Charles Duffy Apr 06 '18 at 17:16
  • ...for others reading this and wondering how to reproduce the OP's bug, by the way, the following will suffice (on a command line, too; it's *not* script-specific): `s="sed -i '4d' file.txt"; $s` – Charles Duffy Apr 06 '18 at 17:25
  • ...okay, now that the question has been updated with an actual reproducer: The backslashes in `sed -e \'$lineNum\' $file` make the quotes literal, meaning they're sent to `sed`, not parsed by the shell. `sed` doesn't expect or understand literal quotes. – Charles Duffy Apr 06 '18 at 20:27
  • 1
    What you *should* be running is more like `sed -e "${lineNum}d" "$file"` -- with *double quotes* around expansions (all of them, filename included). – Charles Duffy Apr 06 '18 at 20:29
  • BTW, assertion made in question text notwithstanding, `sed -e \'$lineNum\' $file` doesn't work in interactive command-line use either. – Charles Duffy Apr 06 '18 at 20:30
  • @CharlesDuffy I tried using `bash -x` as you said, (I actually never heard of that before) and now I know the expression was actually evaluating to `+ sed -i ''\''3d'\''' file2.txt` which made me think "why am I even trying to send the single quotes if they are not actually needed?" so I just changed the command to `sed -i $lineNum $file` and it works, but I like your approach better since I don't have to concatenate the 'd' separately to the variable. On the other hand, if in the future I actually need the single quotes to be included, how would I go about that? – Artemio Ramirez Apr 06 '18 at 20:34
  • 1
    @ArtemioRamirez, `sed` can't actually tell what kind of quotes were used -- when a program is invoked in C (and bash, the operating system kernel, &c. are all using this interface), its argument vector is an array of C strings; the quotes are just hints to the shell in how to operate in building that array. So using double quotes to allow an expansion to take place has the exact same behavior as a single-quoted literal string with the value that expansion would create. – Charles Duffy Apr 06 '18 at 20:40
  • BTW, consider making a practice of running your scripts through http://shellcheck.net/ for automated feedback around common mistakes &c. – Charles Duffy Apr 06 '18 at 20:41
  • @CharlesDuffy That makes sense, wish I knew that before, it really makes thing a lot clearer, thanks. Thanks for the shellcheck.net tip too will surely come in handy as I'm learning sh/ksh alone – Artemio Ramirez Apr 06 '18 at 20:45

0 Answers0