How can I tail a log file and add command: word on every line before output in a different file? - bash

trying to tail and grep certain logs with $installingFil and adding Command: word before output in $DNLOGfile, but file is empty /private/tmp/DownLog.log
What will be the correct approach to echo "Command:" before every line.
I am not able to add/echo "Command:" word before every line which is output in /private/tmp/DownLog.log
like:-
Command: bla bla
Command: downloding finish
Scrip -
#!/bin/bash
downFil=$(tail -f /var/log/system.log | grep 'Downloading files of')
dLog="/private/tmp/DownLog.log"
if [ -f /var/log/system.log ]; then
echo "Command:" "$downFil" >> "$dLog" # dLog is blank
else
echo "Command: Please wait.." >> $dLog # this works fine
fi

If I understand you correctly, you should try:
tail -f /var/log/system.log | grep 'Downloading files of' | sed 's/^/Command: /' >> /private/tmp/DownLog.log

Related

Concatenate the output of 2 commands in the same line in Unix

I have a command like below
md5sum test1.txt | cut -f 1 -d " " >> test.txt
I want output of the above result prefixed with File_CheckSum:
Expected output: File_CheckSum: <checksumvalue>
I tried as follows
echo 'File_Checksum:' >> test.txt | md5sum test.txt | cut -f 1 -d " " >> test.txt
but getting result as
File_Checksum:
adbch345wjlfjsafhals
I want the entire output in 1 line
File_Checksum: adbch345wjlfjsafhals
echo writes a newline after it finishes writing its arguments. Some versions of echo allow a -n option to suppress this, but it's better to use printf instead.
You can use a command group to concatenate the the standard output of your two commands:
{ printf 'File_Checksum: '; md5sum test.txt | cut -f 1 -d " "; } >> test.txt
Note that there is a race condition here: you can theoretically write to test.txt before md5sum is done reading from it, causing you to checksum more data than you intended. (Your original command mentions test1.txt and test.txt as separate files, so it's not clear if you are really reading from and writing to the same file.)
You can use command grouping to have a list of commands executed as a unit and redirect the output of the group at once:
{ printf 'File_Checksum: '; md5sum test1.txt | cut -f 1 -d " " } >> test.txt
printf "%s: %s\n" "File_Checksum:" "$(md5sum < test1.txt | cut ...)" > test.txt
Note that if you are trying to compute the hash of test.txt(the same file you are trying to write to), this changes things significantly.
Another option is:
{
printf "File_Checksum: "
md5sum ...
} > test.txt
Or:
exec > test.txt
printf "File_Checksum: "
md5sum ...
but be aware that all subsequent commands will also write their output to test.txt. The typical way to restore stdout is:
exec 3>&1
exec > test.txt # Redirect all subsequent commands to `test.txt`
printf "File_Checksum: "
md5sum ...
exec >&3 # Restore original stdout
Operator &&
e.g. mkdir example && cd example

Bash - catch the output of a command

I am trying to check the output of a command and run different commands depending on the output.
count="1"
for f in "$#"; do
BASE=${f%.*}
# if [ -e "${BASE}_${suffix}_${suffix2}.mp4" ]; then
echo -e "Reading GPS metadata using MediaInfo file ${count}/${##} "$(basename "${BASE}_${suffix}_${suffix2}.mp4")"
mediainfo "${BASE}_${suffix}_${suffix2}.mp4" | grep "©xyz" | head -n 1
if [[ $? != *xyz* ]]; then
echo -e "WARNING!!! No GPS information found! File ${count}/${##} "$(basename "${BASE}_${suffix}_${suffix2}.mp4")" || exit 1
fi
((count++))
done
MediaInfo is the command I am checking the output of.
If a video file has "©xyz" atom written into it the output looks like this:
$ mediainfo FILE | grep "©xyz" | head -n 1
$ ©xyz : +60.9613-125.9309/
$
otherwise it is null
$ mediainfo FILE | grep "©xyz" | head -n 1
$
The above code does not work and echos the warning even when ©xyz presented.
Any ideas of what I am doing wrong?
The syntax you are using the capture the output of the mediainfo command is plain wrong. When using grep you can use its return code (the output of $?) directly in the if-conditional
if mediainfo "${BASE}_${suffix}_${suffix2}.mp4" | grep -q "©xyz" 2> /dev/null;
then
..
The -q flag in grep instructs it to run the command silently without throwing any results to stdout, and the part 2>/dev/null suppresses any errors thrown via stderr, so you will get the if-conditional pass when the string is present and fail if not present
$? is the exit code of the command: a number between 0 and 255. It's not related to stdout, where your value "xyz" is written.
To match in stdout, you can just use grep:
if mediainfo "${BASE}_${suffix}_${suffix2}.mp4" | grep -q "©xyz"
then
echo "It contained that thing"
else
echo "It did not"
fi

grep the log from only START to the end in shell

I want to grep the log from only START to the end in shell
I am using this script but getting only up to TIME as there is a space?
cat cdrdump_test.log |
while read line
do
sed -n 's/.*CDRQ]:\([^ ]*\).*/\1/p;d' >>new_cdrdump_test.log
done
echo "done"
LOG::
2017-02-13 08:16:14,808 [20170213081614665-88] INFO nxl.vxml.manager.VxmlSessionManager ( 807) - [TRX-20170213081614665-88][CALLFLOW] [CDRQ]:START|START|>>ACTION=TM2CM.ALERTING,SYSTEMIDENTIFIER=192.168.100.10,SESSIONID=20170213081614665-88,MSISDN=773930863,CHANNEL=24,DNIS=851851255777759523,TYPE=IBD,CID=-1,TRUNK=2,VXML=null,BOARD=1,DOMAIN=GSM,PROMO=DEFAULT,DIAL_TIME=null,OPTIONS={},TIME=13-02-2017 08:16:14.0666|STARTTIME=1486984574666|<>ACTION=TM2CM.CONNECTED,SYSTEMIDENTIFIER=192.168.100.10,SESSIONID=20170213081614665-88,TIME=13-02-2017 08:16:14.0760|<>ACTION=CM2CM.LOG,SYSTEMIDENTIFIER=192.168.100.10,SESSIONID=20170213081614665-88,MESSAGE=CRBT_STATUS:NoRecord,TIME=13-02-2017 08:16:14.0806|<
echo "started "
cat cdrdump_test.log| while read line
do
sed -n 's/.CDRQ]:(.)./\1/p;d' >>DeleteEND.log
done
echo "start1"
cat DeleteEND.log| while read line
do
sed s/'\w$'// >>Final_test.log
done
echo "end"

extract file content using a bash script

It has been long time since my last bash script.
I m just trying to extract the content of a file from the the start variable to the stop one.
My source file is night4.info and it contains a list of .jpg files.The structure of this file is similar to:
./2014-11-02/18h/00mn/2014-11-02T18-00-00.048000-depth.jpg
./2014-11-02/18h/00mn/2014-11-02T18-00-00.182000-depth.jpg
./2014-11-02/18h/00mn/2014-11-02T18-00-00.316000-depth.jpg
This is the code so far :
#! /bin/bash
start=$(grep -n $1 night4.info | cut -d : -f 1)
stop=$(grep -n $2 night4.info | cut -d : -f 1)
echo "1" >> list.info
sed -n -e "$start,$stop p" night4.info >> list.info
And this is how I m running my script:
./script1.sh 2014-11-02T18-00-00.048000 2014-11-03T06-59-59.981000
There is no error message and the code doesn't give the right output.
You could use a Perl one-liner with the range operator:
perl -ne "print if /\Q$1\E/../\Q$2\E/" night4.info >> list.info

Redirect grep output to file

I am not sure as to why that redirection provided in the code does not work. Every time I run the script, the output file is always empty. Does anyone have an idea on that?
Thanks.
#!/bin/sh
LOOK_FOR="DefaultProblem"
FILES=`ls plugins/*source*.jar`
for i in $FILES
do
# echo "Looking in $i ..."
unzip -p $i | grep -i $LOOK_FOR > output #> /dev/null
if [ $? == 0 ]
then
echo ">>>> Found $LOOK_FOR in $i <<<<"
fi
done
You may want to use >> (append) instead of > (overwrite) for redirection as:
unzip -p $i | grep -iF "$LOOK_FOR" >> output
Since you're executing this command in a loop and overwriting file output every time, it might be blank in the end if very last command with grep doesn't find any matching line in unzip output.
You have three problems
Don't try to parse the output of ls. Instead just use for i in plugins/*source*.jar The major reason is that your script will completely and utterly break on any files that have spaces in their names. See this link for a litany of reasons why not to parse ls
You need to use >> instead of > as the latter will overwrite the output file on each iteration of the loop. The former will append to it
Use more quotes! You'll want to quote your variables to make sure they aren't subjected to word splitting
Also, you can inline the if test. So putting it all together we have:
#!/bin/sh
LOOK_FOR="DefaultProblem"
for i in plugins/*source*.jar
do
# echo "Looking in $i ..."
if unzip -p "$i" | grep -i "$LOOK_FOR" >> output #> /dev/null
then
echo ">>>> Found $LOOK_FOR in $i <<<<"
fi
done
You can redirect the output of the entire loop:
#!/bin/sh
LOOK_FOR="DefaultProblem"
FILES=`ls plugins/*source*.jar`
for i in $FILES ; do
# echo "Looking in $i ..." 1>&2
unzip -p $i | grep -i $LOOK_FOR
if [ $? == 0 ] ; then
echo ">>>> Found $LOOK_FOR in $i <<<<" 1>&2
fi
done > output
Note that I've redirected the diagnostic messages to stderr.
Instead of a for loop and an if conditional you can do everything in one find command
find /path/to/plugins -name "*source*.jar" -exec sh -c 'unzip -l "{}" | grep -q DefaultProblem' \; -print

Resources