0

Is there a command that takes as input another command (which may or may not include the control operators &&, ||, ; and possibly others that might be relevant) and breaks the command into its "sub commands"?

For example:

echo 1 && ls --invalid-option 2>/dev/null || echo 3

Would be broken down into:

  • echo 1
  • ls --invalid-option 2>/dev/null or possibly ls --invalid-option
  • echo 3
  • What is a "token" for your use case? In conventional terms echo and 1 are separate tokens. – Michael Homer May 9 at 9:50
  • @MichaelHomer Thanks, I wasn't aware. I edited the question. Is it clearer now? – user352096 May 9 at 9:52
  • 2
    Yeah, I think that's clear. I don't have an answer to it - parsing shell is notoriously complicated - but someone might know. – Michael Homer May 9 at 9:53
1

Parsing shell syntax is a huge job and is usually not easily done.

However, if you're fine with running the line once, then you can let the shell do it, with set -x:

wsl@win10:~ $ set -x
wsl@win10:~ $ echo 1 && ls haha &> /dev/null; pwd
+ echo 1
1
+ ls --color=auto haha
+ pwd
/home/wsl
wsl@win10:~ $

As you can note, there's one caveat: alias expansion (all expansion, actually).

To extract the actual commands would probably be an interesting little after-school task for readers (hint: lines starting with a plus and a space).

0

Using sed in a very basic, limited approach:

# Utility functions: print-as-echo, print-line-with-visual-space.
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }

pl " Input data file $FILE:"
head $FILE

pl " Input data file $FILE, invisibles marked:"
cat -A $FILE

pl " Results:"
sed -e 's/[      ]*&&[   ]*/\n/g' -e 's/[       ]*||[   ]*/\n/g' $FILE

producing:

-----
 Input data file data2:
one-space && next-one || last-one

one-TAB &&      next-tab        ||      last-tab

mixed-tabs-space         &&             next-mixed        ||    last-mixed

-----
 Input data file data2, invisibles marked:
one-space && next-one || last-one$
$
one-TAB^I&&^Inext-tab^I||^Ilast-tab$
$
mixed-tabs-space ^I && ^I^Inext-mixed^I  ||  ^Ilast-mixed$

-----
 Results:
one-space
next-one
last-one

one-TAB
next-tab
last-tab

mixed-tabs-space
next-mixed
last-mixed

In a system like:

OS, ker|rel, machine: Linux, 3.16.0-7-amd64, x86_64
Distribution        : Debian 8.11 (jessie) 
sed (GNU sed) 4.2.2

The [] enclose a TAB and a space, so any number of such white-space characters are allowed. This does not take into account quoted strings, etc.

Best wishes ... cheers, drl

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.