How to concatenate the result of two linux commands? - linux

Is there an easy way to concatenate the result of two linux commands, in one line? (i.e without using variables)
I pull the local outdoor temperature from a nearby weather station. The result today is:
5.2
I simply want to add the units, so result should look like this:
5.2°C
An example command, that almost gives me what I want is:
wget -q -O- "http://meteocentre.com/montreal/home_e.html" | grep -oP '(?<=Tn= ).*(?=&deg)' ; printf "°C\n"

You are already concatenating the results.
wget .. | grep .. outputs: 5.2\n
printf outputs °C\n
The concatenated result is therefore 5.2\n°C\n , exactly what you're getting.
What you want to do is strip the linefeed after 5.2. You can take advantage of the fact that $(command substitution) strips trailing linefeeds and pass it to printf:
printf '%s°C\n' "$(wget -q -O- "http://meteocentre.com/montreal/home_e.html" | grep -oP '(?<=Tn= ).*(?=&deg)')"

in bash, add pipe at the end:
echo $(cat) [more text]
or
echo `cat` [more text]
example:
wget -q -O- "http://meteocentre.com/montreal/home_e.html" | grep -oP '(?<=Tn= ).*(?=&deg)' | echo $(cat) °C
-> 5.2 °C

Related

Different behaviour for these commands

I'm having trouble understanding why there is a difference in the outputs of these 3 commands when executed on different distributions
Could you guys help me understand why ?
printf "%s" `echo ../.. | sed 's/[.]/\\&/g'`
output on kali: &&/&&~ output on ubuntu: &&/&&
printf "%s" $(echo ../.. | sed 's/[.]/\\&/g')
output on kali: \.\./\.\. output on ubuntu: ../..
printf "%s" "$(echo ../.. | sed 's/[.]/\\&/g')"
output on kali: \.\./\.\. output on ubuntu: \.\./\.\.
Kali uses Zsh shell. Ubuntu uses Bash shell.
output on ubuntu: &&/&&
Do not use backticks - prefer $(...). Backticks remove \ before execution.
printf "%s" `echo ../.. | sed 's/[.]/\\&/g'`
becomes:
printf "%s" $(echo ../.. | sed 's/[.]/\&/g')
So replaces . by & character.
output on kali: &&/&&~
The ~ on the end in Zsh in your configuration represents output from a command without a newline.
output on ...: \.\./\.\.
That should be understandable.
output on ubuntu: ../..
Aaaand this is the hard one around Bash 5.0. Unquoted result of command substitution undergo filename expansion (also called pathname expansion). The \.\./\.\. matches the directory path ../... Bash 5.0 introduced a change that would make the result of expansion undergo pathname expansion even if it doesn't have any globbing special characters.
The change was reversed in Bash 5.1. Bash-5.1-alpha available for download https://lists.gnu.org/archive/html/bug-bash/2019-01/msg00063.html.

Grep special character #‘

trying to grep "#‘om" but not able to escape or account for the quote char. I tried grep -F, grep -e, grep -n or simply grep "#\‘om" to no avail.
That quote is not the simple quote character it appears to be. It's not clear whether copying-and-pasting the quote character from this website is accurate.
$ echo '‘' | cat -v
M-bM-^#M-^X
$ echo '‘' | xxd
$ 00000000: e280 980a ....
So, it appears the problem is one of character sets.
Note, however, that the following works for me:
$ echo '‘' | grep -F '‘'
‘
As does the following:
$ echo '#‘om' | grep -F '#‘om'
#‘om
It would help to see exactly what is being tried. Perhaps use xxd to confirm what bytes are making up that quote.

using sed to set a variable works on command line, but not bash script

I have looked quite a bit for answers but I am not finding any suggestions that have worked so far.
on command line, this works:
$ myvar=$( cat -n /usr/share/dict/cracklib-small | grep $myrand | sed -e "s/$myrand//" )
$ echo $myvar
$ commonness
however, inside a bash script the same exact lines just echoes out a blank line
notes - $myrand is a number, like 10340 generated with $RANDOM
cat prints out a dictionary with line numbers
grep grabs the line with $myrand in it ; e.g. 10340 commonness
sed is intended to remove the $myrand part of the line and replace it with nothing. here is my sample script
#!/bin/bash
# prints out a random word
myrand=$RANDOM
export myrand
myword=$( cat -n /path/to/dict/cracklib-small | grep myrand | sed -e "s/$myrand//g" <<<"$myword" )
echo $myword
Your command line code is running:
grep $myrand
Your script is running:
grep myrand
These are not the same thing; the latter is looking for a word that contains "myrand" within it, not a random number.
By the way -- I'd suggest a different way to get a random line. If you have GNU coreutils, the shuf tool is built-to-purpose:
myword=$(shuf -n 1 /path/to/dict/cracklib-small)
#!/bin/bash
# prints out a random word
myrand=$RANDOM
export myrand
myword=$( cat -n /path/to/dict/cracklib-small | grep myrand | sed -e "s/$myrand//g" <<<"$myword" )
echo $myword
where is the $ sign in grep myrand ?
you must put in some work before posting it here.

UNIX shell script to run a list of grep commands from a file and getting result in a single delimited file

I am beginner in unix programming and a way to automate my work
I want to run a list a grep commands and get the output of all the grep command in a in a single delimited file .
i am using the following bash script. But it's not working .
Mockup sh file:
!/bin/sh
grep -l abcd123
grep -l abcd124
grep -l abcd125
and while running i used the following command
$ ./Mockup.sh > output.txt
Is it the right command?
How can I get both the grep command and output in the output file?
how can i delimit the output after each command and result?
How can I get both the grep command and output in the output file
You can use bash -v (verbose) to print each command before execution on stderr and it's output will be as usual be available on stdout:
bash -v ./Mockup.sh > output.txt 2>&1
cat output.txt
Working Demo
A suitable shell script could be
#!/bin/sh
grep -l 'abcd123\|abcd124\|abcd125' "$#"
provided that the filenames you pass on the invocation of the script are "well behaved", that is no whitespace in them. (Edit Using the "$#" expansion takes care of generic whitespace in the filenames, tx to triplee for his/her comment)
This kind of invocation (with alternative matching strings, as per the \| syntax) has the added advantage that you have exactly one occurrence of a filename in your final list, because grep -l prints once the filename as soon as it finds the first occurrence of one of the three strings in a file.
Addendum about "$#"
% ff () { for i in "$#" ; do printf "[%s]\n" "$i" ; done ; }
% # NB "a s d" below is indeed "a SPACE s TAB d"
% ff "a s d" " ert " '345
345'
[a s d]
[ ert ]
[345
345]
%
cat myscript.sh
########################
#!/bin/bash
echo "Trying to find the file contenting the below string, relace your string with below string"
grep "string" /path/to/folder/* -R -l
########################
save above file and run it as below
sh myscript.sh > output.txt
once the command prmpt get return you can check the output.txt for require output.
Another approach, less efficient, that tries to address the OP question
How can I get both the grep command and output in the output file?
% cat Mockup
#!/bin/sh
grep -o -e string1 -e string2 -e string3 "$#" 2> /dev/null | sort -t: -k2 | uniq
Output: (mocked up as well)
% sh Mockup file{01..99}
file01:string1
file17:string1
file44:string1
file33:string2
file44:string2
file48:string2
%
looking at the output from POV of a consumer, one foresees problems with search strings and/or file names containing colons... oh well, that's another Q maybe

Piped Arguments: echo "value1 value2" | command $1 $2

I have used Sed to grab two interesting values. Now I want to send those two values as parameters to Curl. I have been successful piping Sed output to Curl with only 1 argument using xargs, however I am unable to use two arguments for one command.
echo "value1" "value2" | curl --data 'valA=$1&valB=$2' http://example.com
I am stuck in both theory and practice. I wasn't planning to use bash scripting.
[ I am running tshark, piping output to sed, and hoping to pipe that output to curl so as to record data in a remote DB. ]
As long as you're not expecting to use valA and valB in future commands, you can use read to store the the whitespace-delimited output from your exiting commands:
$ echo foo bar | { read var1 var2 ; echo $var1 $var2 ; }
foo bar
Which means you can do:
echo "value1" "value2" | { read a b ; curl --data 'valA=$a&valB=$b' http://example.com ; }
Assuming you can get sed to output something like .csv (foo\tbar):
tshark | sed ... | parallel --colsep '\t' -q curl --data 'valA={1}&valB={2}' http://example.com
You can find more about GNU Parallel at:
http://www.gnu.org/s/parallel/
Watch the intro video on
http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Walk through the tutorial (man parallel_tutorial). Your command line will love you for it.
Backticks sound like the best bet, if you can't run the sed twice (eg you're doing this on a live tshark stream):
curl --data $(printf "valA=%s&valB=%s" `tshark --whatever | sed -e whatever`)

Resources