srvctl add database -d MYDB -o /path/to/home is not a Linux command, it's code in the language of most Unix shells that most Unix shells interpret as executing a file (something like /usr/bin/srvctl) whose path is looked up in directories of $PATH with a number of arguments (srvctl, add, database, -d, MYDB, -o, /path/to/home) in a child process and wait for its termination.
In the perl language, the equivalent would be:
system("srvctl", "add", "database", "-d", "MYDB", "-o", "/path/to/home")
So what you want here is run the srvctl command with srvctl, config, database, -d, MYDB as arguments, collect its output and extract information for that to pass as the arguments following -d and -o in the command above.
perl backronymed as practical extration and report language is the perfect tool to extract information from text.
From a POSIX-like or rc-like shell (or fish), you could do for instance:
LC_ALL=C srvctl config database -d MYDB | perl -lwne ' if (/^\s*(.*?)\s*: (.*?)\s*$/) { $f{lc($1)} = $2; } END { exec( "srvctl", "add", "database", "-d", $f{"database unique name"}, "-o", $f{"oracle home"} ) || die "Can't run srvctl: $!\n" }'
Where the shell runs the srvctl config and perl commands with a pipe connecting the standard output of the former to the standard input of the latter, and perl parses that output to build an associative arrays and in the END executes srvctl by itself (with exec(), so in the same process, not a child) with some of the arguments being some of the elements of the associative array.
Note the LC_ALL=C which should ensure those Database unique name, Oracle home are not translated to the language of the user, if not English.
Also note the -w option which enables a few warnings and in particular here will warn you if elements with database unique name or oracle home keys are not found in the %f associative array (but will still run the srvctl with empty arguments in place of the missing elements).
You could also do it the whole thing in perl which would make it a bit more complicated but would allow us to check the exit status of srvctl config before running srvctl add. Doing it with maximum error checking:
#! /usr/bin/perl -- use POSIX; $ENV{LC_ALL} = "C"; open(my $output, "-|", qw(srvctl config database -d MYDB)) or die "Can't start srvctl config: $!"; my %field; while (<$output>) { if (/^\s*(.*?)\s*: (.*?)\s*$/) { $field{lc($1)} = $2; } } unless (close($output)) { if ($!) { die "Error closing pipe to srvctl config: $!"; } elsif (WIFSIGNALED(${^CHILD_ERROR_NATIVE})) { die "srvctl config was killed by signal " . WTERMSIG(${^CHILD_ERROR_NATIVE}); } else { die "srvctl config failed with exit status " . WEXITSTATUS(${^CHILD_ERROR_NATIVE}); } } sub get_field { return $field{$_[0]} // die "Could not find $_[0] in srvctl config output" } exec( "srvctl", "add", "database", "-d", get_field("database unique name"), "-o", get_field("oracle home") ) || die "Can't run srvctl add: $!\n";
A few shells have associative array support and builtin pattern matching support.
For instance, in zsh (which also supports perl-like regexps), something similar could be done with:
#! /bin/zsh - lines=( ${(f)"$(LC_ALL=C srvctl config database -d MYDB)"} ) || exit typeset -A field set -o re_match_pcre for line ($lines) [[ line =~ '^\s*(.*?)\s*: (.*?)\s*$' ]] && field[$match[1]:l]=$match[2] exec srvctl add database \ -d "${field[database unique name]?}" \ -o "${field[oracle home]?}"
srvctl add database -d <placeholder1> -o <placeholder2>and use grep-or-some-other-command to determine the value of each placeholder?