Skip to main content
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/
Source Link

For the general question in your title, head -1 or sed -n 1p -- or sed 1q -- are ways to select the first line of anything.

But your case is to select the first substitution result by sed. You can get that from sed itself with a slight modification, and it can also do the equivalent of your grep and your useless cat, plus you only need one of your capture groups:

sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' # -n don't output input lines by default # /PORT/ when an input line contains the string PORT # {s/.../\1/p; extract only the 4digits after PORT and print them # q} and then terminate sed processing, so we onloy get one value 

ADDED: you can also avoid the backslashing in the regexp if you use -r, as Kaffe answeredas Kaffe answered (while I was drafting), on MOST versions of sed.

Your ssh case has TWO (or three) problems. You do:

ssh user@machine "port=$( commands ) | echo port" 

First, the $( commands ) are within a double-quoted string, so they run on YOUR machine, not the other machine. You are connecting to $maquina but trying (see next) to tell it to print the port number for YOUR machine, which is a waste of time. (And it's not easy to fix this, because you want to subsitute $sid plus use singlequotes for the sed command.)

Second, you do port=value | echo $port. That pipeline runs separate subshells (on the other machine); in the first subshell it sets the variable port to the port number (from your machine) but that variable is never used for anything; in the second subshell it prints the value of the variable port, which is not set in that subshell, so you get an empty line. To put a value in a variable and then use the variable, use ; or if you want to or can depend on its exit status && or ||.

But you don't need any variable. Except for mangling whitespace and expanding globs if present, which they aren't here, var=$(commands); echo $var is exactly the same as commands. Similarly, !echo $maquina! where the ! are actually backticks (I can't find a way to markdown in text) without whitespace or glob (which won't occur in a machine name) is exactly the same as $maquina.

TLDR:

ssh ora$sid@$maquina "sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' " 

For the general question in your title, head -1 or sed -n 1p -- or sed 1q -- are ways to select the first line of anything.

But your case is to select the first substitution result by sed. You can get that from sed itself with a slight modification, and it can also do the equivalent of your grep and your useless cat, plus you only need one of your capture groups:

sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' # -n don't output input lines by default # /PORT/ when an input line contains the string PORT # {s/.../\1/p; extract only the 4digits after PORT and print them # q} and then terminate sed processing, so we onloy get one value 

ADDED: you can also avoid the backslashing in the regexp if you use -r, as Kaffe answered (while I was drafting), on MOST versions of sed.

Your ssh case has TWO (or three) problems. You do:

ssh user@machine "port=$( commands ) | echo port" 

First, the $( commands ) are within a double-quoted string, so they run on YOUR machine, not the other machine. You are connecting to $maquina but trying (see next) to tell it to print the port number for YOUR machine, which is a waste of time. (And it's not easy to fix this, because you want to subsitute $sid plus use singlequotes for the sed command.)

Second, you do port=value | echo $port. That pipeline runs separate subshells (on the other machine); in the first subshell it sets the variable port to the port number (from your machine) but that variable is never used for anything; in the second subshell it prints the value of the variable port, which is not set in that subshell, so you get an empty line. To put a value in a variable and then use the variable, use ; or if you want to or can depend on its exit status && or ||.

But you don't need any variable. Except for mangling whitespace and expanding globs if present, which they aren't here, var=$(commands); echo $var is exactly the same as commands. Similarly, !echo $maquina! where the ! are actually backticks (I can't find a way to markdown in text) without whitespace or glob (which won't occur in a machine name) is exactly the same as $maquina.

TLDR:

ssh ora$sid@$maquina "sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' " 

For the general question in your title, head -1 or sed -n 1p -- or sed 1q -- are ways to select the first line of anything.

But your case is to select the first substitution result by sed. You can get that from sed itself with a slight modification, and it can also do the equivalent of your grep and your useless cat, plus you only need one of your capture groups:

sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' # -n don't output input lines by default # /PORT/ when an input line contains the string PORT # {s/.../\1/p; extract only the 4digits after PORT and print them # q} and then terminate sed processing, so we onloy get one value 

ADDED: you can also avoid the backslashing in the regexp if you use -r, as Kaffe answered (while I was drafting), on MOST versions of sed.

Your ssh case has TWO (or three) problems. You do:

ssh user@machine "port=$( commands ) | echo port" 

First, the $( commands ) are within a double-quoted string, so they run on YOUR machine, not the other machine. You are connecting to $maquina but trying (see next) to tell it to print the port number for YOUR machine, which is a waste of time. (And it's not easy to fix this, because you want to subsitute $sid plus use singlequotes for the sed command.)

Second, you do port=value | echo $port. That pipeline runs separate subshells (on the other machine); in the first subshell it sets the variable port to the port number (from your machine) but that variable is never used for anything; in the second subshell it prints the value of the variable port, which is not set in that subshell, so you get an empty line. To put a value in a variable and then use the variable, use ; or if you want to or can depend on its exit status && or ||.

But you don't need any variable. Except for mangling whitespace and expanding globs if present, which they aren't here, var=$(commands); echo $var is exactly the same as commands. Similarly, !echo $maquina! where the ! are actually backticks (I can't find a way to markdown in text) without whitespace or glob (which won't occur in a machine name) is exactly the same as $maquina.

TLDR:

ssh ora$sid@$maquina "sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' " 
added 194 characters in body
Source Link
dave_thompson_085
  • 4.5k
  • 1
  • 19
  • 16

For the general question in your title, head -1 or sed -n 1p -- or sed 1q -- are ways to select the first line of anything.

But your case is to select the first substitution result by sed. You can get that from sed itself with a slight modification, and it can also do the equivalent of your grep and your useless cat, plus you only need one of your capture groups:

sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' # -n don't output input lines by default # /PORT/ when an input line contains the string PORT # {s/.../\1/p; extract only the 4digits after PORT and print them # q} and then terminate sed processing, so we onloy get one value 

ADDED: you can also avoid the backslashing in the regexp if you use -r, as Kaffe answered (while I was drafting), on MOST versions of sed.

Your ssh case has TWO (or three) problems. You do:

ssh user@machine "port=$( commands ) | echo port" 

First, the $( commands ) are within a double-quoted string, so they run on YOUR machine, not the other machine. You are connecting to $maquina but trying (see next) to tell it to print the port number for YOUR machine, which is a waste of time. (And it's not easy to fix this, because you want to subsitute $sid plus use singlequotes for the sed command.)

Second, you do port=value | echo $port. That pipeline runs separate subshells (on the other machine); in the first subshell it sets the variable port to the port number (from your machine) but that variable is never used for anything; in the second subshell it prints the value of the variable port, which is not set in that subshell, so you get an empty line. To put a value in a variable and then use the variable, use ; or if you want to or can depend on its exit status && or ||.

But you don't need any variable. Except for mangling whitespace and expanding globs if present, which they aren't here, var=$(commands); echo $var is exactly the same as commands. Similarly, !echo $maquina! where the ! are actually backticks (I can't find a way to markdown in text) without whitespace or glob (which won't occur in a machine name) is _exactlyexactly the same as $maquina.

TLDR:

ssh ora$sid@$maquina "sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' " 

For the general question in your title, head -1 or sed -n 1p -- or sed 1q -- are ways to select the first line of anything.

But your case is to select the first substitution result by sed. You can get that from sed itself with a slight modification, and it can also do the equivalent of your grep and your useless cat, plus you only need one of your capture groups:

sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' # -n don't output input lines by default # /PORT/ when an input line contains the string PORT # {s/.../\1/p; extract only the 4digits after PORT and print them # q} and then terminate sed processing, so we onloy get one value 

Your ssh case has TWO (or three) problems. You do:

ssh user@machine "port=$( commands ) | echo port" 

First, the $( commands ) are within a double-quoted string, so they run on YOUR machine, not the other machine. You are connecting to $maquina but trying (see next) to tell it to print the port number for YOUR machine, which is a waste of time. (And it's not easy to fix this, because you want to subsitute $sid plus use singlequotes for the sed command.)

Second, you do port=value | echo $port. That pipeline runs separate subshells (on the other machine); in the first subshell it sets the variable port to the port number (from your machine) but that variable is never used for anything; in the second subshell it prints the value of the variable port, which is not set in that subshell, so you get an empty line. To put a value in a variable and then use the variable, use ; or if you want to or can depend on its exit status && or ||.

But you don't need any variable. Except for mangling whitespace and expanding globs if present, which they aren't here, var=$(commands); echo $var is exactly the same as commands. Similarly, !echo $maquina! where the ! are actually backticks (I can't find a way to markdown in text) without whitespace or glob (which won't occur in a machine name) is _exactly the same as $maquina.

TLDR:

ssh ora$sid@$maquina "sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' " 

For the general question in your title, head -1 or sed -n 1p -- or sed 1q -- are ways to select the first line of anything.

But your case is to select the first substitution result by sed. You can get that from sed itself with a slight modification, and it can also do the equivalent of your grep and your useless cat, plus you only need one of your capture groups:

sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' # -n don't output input lines by default # /PORT/ when an input line contains the string PORT # {s/.../\1/p; extract only the 4digits after PORT and print them # q} and then terminate sed processing, so we onloy get one value 

ADDED: you can also avoid the backslashing in the regexp if you use -r, as Kaffe answered (while I was drafting), on MOST versions of sed.

Your ssh case has TWO (or three) problems. You do:

ssh user@machine "port=$( commands ) | echo port" 

First, the $( commands ) are within a double-quoted string, so they run on YOUR machine, not the other machine. You are connecting to $maquina but trying (see next) to tell it to print the port number for YOUR machine, which is a waste of time. (And it's not easy to fix this, because you want to subsitute $sid plus use singlequotes for the sed command.)

Second, you do port=value | echo $port. That pipeline runs separate subshells (on the other machine); in the first subshell it sets the variable port to the port number (from your machine) but that variable is never used for anything; in the second subshell it prints the value of the variable port, which is not set in that subshell, so you get an empty line. To put a value in a variable and then use the variable, use ; or if you want to or can depend on its exit status && or ||.

But you don't need any variable. Except for mangling whitespace and expanding globs if present, which they aren't here, var=$(commands); echo $var is exactly the same as commands. Similarly, !echo $maquina! where the ! are actually backticks (I can't find a way to markdown in text) without whitespace or glob (which won't occur in a machine name) is exactly the same as $maquina.

TLDR:

ssh ora$sid@$maquina "sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' " 
Source Link
dave_thompson_085
  • 4.5k
  • 1
  • 19
  • 16

For the general question in your title, head -1 or sed -n 1p -- or sed 1q -- are ways to select the first line of anything.

But your case is to select the first substitution result by sed. You can get that from sed itself with a slight modification, and it can also do the equivalent of your grep and your useless cat, plus you only need one of your capture groups:

sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' # -n don't output input lines by default # /PORT/ when an input line contains the string PORT # {s/.../\1/p; extract only the 4digits after PORT and print them # q} and then terminate sed processing, so we onloy get one value 

Your ssh case has TWO (or three) problems. You do:

ssh user@machine "port=$( commands ) | echo port" 

First, the $( commands ) are within a double-quoted string, so they run on YOUR machine, not the other machine. You are connecting to $maquina but trying (see next) to tell it to print the port number for YOUR machine, which is a waste of time. (And it's not easy to fix this, because you want to subsitute $sid plus use singlequotes for the sed command.)

Second, you do port=value | echo $port. That pipeline runs separate subshells (on the other machine); in the first subshell it sets the variable port to the port number (from your machine) but that variable is never used for anything; in the second subshell it prints the value of the variable port, which is not set in that subshell, so you get an empty line. To put a value in a variable and then use the variable, use ; or if you want to or can depend on its exit status && or ||.

But you don't need any variable. Except for mangling whitespace and expanding globs if present, which they aren't here, var=$(commands); echo $var is exactly the same as commands. Similarly, !echo $maquina! where the ! are actually backticks (I can't find a way to markdown in text) without whitespace or glob (which won't occur in a machine name) is _exactly the same as $maquina.

TLDR:

ssh ora$sid@$maquina "sed </ora$sid/dbs/listener.ora -n '/PORT/{s/.*PORT.*\([0-9]\{4\}\).*/\1/p;q}' "