9

Sometimes I need to exec a single command which is in a shell script.

I already know sed -n 'line_num p' can print that line. But how can I exec that printed out specific line as a command?

8

Try this guy =) :

sed -n 'line_num p' | bash

or

"$(sed -n 'line_num p')"
  • @mikeserv I'm interested in knowing the context of that statement for my own education. – Bratchley Jan 12 '15 at 4:05
  • No need to put a space between line_num and p, so for example if line_num is 123, then you can sed -n 123p | bash. And if sh is enough, then just use sh instead of bash. – janos Jan 12 '15 at 21:09
  • So, sed -n 'line_num p' | sh could be another solution? Is this one has more compatibility? – Zen Jan 13 '15 at 2:27
  • 1
    @Zen - that depends on what shell is targeted for the script. It also depends on what shell sh actually is. On Debian (and derived) systems sh is usually dash. If the script is written for dash (or otherwise relies on portable syntax) then probably, yeah, but if it is written for bash then almost definitely not. – mikeserv Jan 13 '15 at 3:50
  • could this be done with the history file so that if I run history and I see that I want to run line 900, can I run line 900 somehow? – codecowboy Dec 8 '15 at 10:08
2

If you're doing this interactively, you could write the line into the bash history:

history -s "$(sed -n 'line_num p')"

Then press Enter to insert the line into the readline buffer, and execute it; that gives you a chance to glance at the line before it's too late.

  • Thats pretty clever, and probably a good assumption. – mikeserv Jan 12 '15 at 22:26
  • what does this -s option mean here? I can't find explanations in man history – Zen Jan 13 '15 at 2:24
  • @zen: history is a built-in, so it is documented in help history (or man bash, but that's a lot of reading). Quoting the above, history -s will "append the ARGs to the history list as a single entry" – rici Jan 13 '15 at 3:49
1

You can do...

{ head -n"$((NUM-1))"; IFS= read -r line; } </path/to/script >/dev/null
eval "$line"

That will get only the $NUM line from your script in the shell variable $line and then evaluate it as a command in the current shell.

Another way to do this could look like:

 </path/to/script sed "${NUM}q;d" >/tmp/"$$"
 . /tmp/"$$" ; rm /tmp/"$$"
  • 1
    'eval' is a common misspelling of 'evil'. If eval is the answer, surely you are asking the wrong question. See mywiki.wooledge.org/BashFAQ/048 – Gilles Quenot Jan 12 '15 at 3:46
  • 1
    Yup. Everybody loves eval. – mikeserv Jan 12 '15 at 8:55
  • gnu sed has the e flag so something like sed "${NUM}"'!d;s/^//e;q' would also work – don_crissti Oct 28 '16 at 19:17
1

Are you editing your script with vim (vi on Linux)? In vi add a mapping:

:nmap <F4> Y:!<C-R>"<C-H><CR>

and afterwards when you are on the interesting line in vi press F4

-2

In bash you can run the following command:

for line in $(cat file.txt); do command $line; done

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.