unix command to redirects output to a file - unix

I am trying to write a unix command which will write/redirects the output to a file i.e. create a file if there is difference in 2 files else it will not create the file.
I am using the below command but it always creates a file(of 0B if no diff), no matter there is any difference in file or not.
diff -u -w a.txt b.txt > diff.tmp
I am trying to write a single unix command that will create file "diff.tmp" if "a.txt" is not equal to "b.txt" else "diff.tmp" will not be created.
Thanks in advance,
Pritish

In bash you could remove it afterwards:
diff -u -w a.txt b.txt > diff.tmp && if [ -f diff.tmp ] && [ ! -s diff.tmp ]; then rm diff.tmp; fi
Note:
-f: to check if the file exits (-e to check if a file, directory, etc. exists)
-s: to check if the file is non-zero

However can will work for text files ..you can use cmp command as well.
cmp a.txt b.txt > cmp.tmp && if [ -f cmp.tmp ] && [ ! -s cmp.tmp ]; then rm cmp.tmp; fi

you can check return code of diff. From man page:
Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
So I would write something like:
#!/bin/bash
diff "$1" "$2" 2>/dev/null 1>/dev/null
if [[ $? -eq 0 ]];then
echo "No diff found!"
else
echo "Diff saved in file "$3
diff $1 $2 > $3
fi
And then you call it like
./diff.sh a.txt b.txt diff.tmp
Hope it helps!
Bye
Piero

Related

How to tell script to look only into a specific folder

I'm trying to make a recycle bin for UNIX, so I have two scripts. 1 to delete the file and move it to the bin, the other script to restore the file back to its original location.
my restore script only works if the person gives the path to the deleted file.
ex: sh restore ~/trashbin/filename
How do I hardcode into my script so that I don't need to give the path to the deleted file it should already know to look in the trashbin for the file. My restore script works only when someone calls in the path to the file.
#!/bin/bash
rlink=$(readlink -e "$1")
rname=$(basename "$rlink")
function restoreFile() {
rlink=$(readlink -e "$1")
rname=$(basename "$rlink")
rorgpath=$(grep "$rname" ~/.restore.info | cut -d":" -f2)
rdirect=$(dirname "$rorgpath")
#echo $orgpath
if [ ! -d "$rdirect" ]
then
mkdir -p $rdirect
#echo $var
mv $rlink $rorgpath
else
mv $rlink $rorgpath
fi
}
if [ -z "$1" ]
then
echo "Error no filename provided."
exit 1
elif [ ! -f "$1" ]
then
echo "Error file does not exist."
exit 1
elif [ -f "$rorgpath" ]
then
echo "File already exists in original path."
read -p "Would you like to overwrite it? (y/n)" ovr
if [[ $ovr = y || $ovr = Y || $ovr = yes ]]
then
echo "Restoring File and overwriting."
restoreFile $1
grep -v "$rname" ~/.restore.info > ~/.restorebackup.info
mv ~/.restorebackup.info ~/.restore.info
fi
else
echo "Restoring file into original path."
restoreFile $1
grep -v "$rname" ~/.restore.info > ~/.restorebackup.info
mv ~/.restorebackup.info ~/.restore.info
fi
When you "remove" the file from the file-system to your trash-bin, move it so that its path is remembered. Example: removing file /home/user/file.txt should mean moving this file to ~/.trash/home/user/file.txt. That way, you'll be able to restore files to the original location, and you'll have auto-complete work, since you can do: sh restore ~/.trash/<TAB><TAB>

Unix — run one script when wc of the file not matched

I want to run the script with different parameters if the wc of the text file is matched or not matched!
My Script:
#!/bin/sh
x= echo `wc -l "/scc/ftp/mrdr_rpt/yet_to_load.txt"`
if [ $x -gt 0 ]
then
sh /scc/ftp/mrdr_rpt/eam.ksh /scc/ftp/mrdr_rpt/vinu_mrdr_rpt.txt /scc/ftp/mrdr_rpt/yet_to_load.txt from#from.com to.name#to.com
elif
sh /scc/ftp/mrdr_rpt/eam.ksh /scc/ftp/mrdr_rpt/vinu_mrdr_rpt.txt /scc/ftp/mrdr_rpt/yet_to_load.txt from#from.com to.name#to.com, hi.name#hi.com
fi
You need to capture the output of wc accurately, and you need to avoid getting a file name in its output. You have:
x= echo `wc -l "/scc/ftp/mrdr_rpt/yet_to_load.txt"`
if [ $x -gt 0 ]
The space after the = is wrong. The echo is not wanted. You should use input redirection with wc. (wc is a little peculiar. If you give it a file name to process, it includes the file name in the output; if you have it process standard input, it doesn't include a file name in the output.) You should use $(…) in preference to back-quotes.
x=$(wc -l < "/scc/ftp/mrdr_rpt/yet_to_load.txt")
if [ $x -gt 0 ]
If you want to check if the file is not empty (rather than being a file with data but no newlines), then you can use a more direct test:
if [ -s "/scc/ftp/mrdr_rpt/yet_to_load.txt" ]
You should probably be using a name such as
DIR="/scc/ftp/mrdr_rpt"
and then referencing it to reduce the ugly repetitions in your code:
if [ $x -gt 0 ]
then
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" \
from#from.com to.name#to.com
else
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" \
from#from.com to.name#to.com, hi.name#hi.com
fi
However, I think the comma in the second line is probably not needed, and it might be better to use:
who="from#from.com to.name#to.com"
if [ -s "$DIR/yet_to_load.txt" ]
then who="$who hi.name#hi.com"
fi
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" $who
Then you've only one line with all the names in it. And you might do even better with an array instead of string:
who=("from#from.com" "to.name#to.com")
if [ -s "$DIR/yet_to_load.txt" ]
then who+=("$who hi.name#hi.com" "Firstname Lastname <someone#example.com>")
fi
sh "$DIR/eam.ksh" "$DIR/vinu_mrdr_rpt.txt" "$DIR/yet_to_load.txt" "${who[#]}"
Using arrays means you can handle blanks in the names correctly where a simple string doesn't.

Not getting expected file result using awk

#!/bin/bash
delete_file () {
for file in processor_list.txt currnet_username.txt unique_username.txt
do
if [ -e $file ] ;then
rm $file
fi
done
}
delete_file
ps -elf > processor_list.txt ; chmod 755 processor_list.txt
awk '{print $3}' processor_list.txt > currnet_username.txt ; chmod 755 currnet_username.txt
sort -u currnet_username.txt > unique_username.txt ;chmod 755 unique_username.txt
while read line ; do
if [ -e $line.txt ] ;then
rm $line.txt
fi
grep $line processor_list.txt >$line.sh ;chmod 755 $line.sh
awk '{if($4 == "$line") print $0;}' $line.sh > ${line}1.txt ; #mv ${line}1.txt $line.txt;chmod 755 $line.txt
done < unique_username.txt
I'm a beginner of unix shell scripting. please suggested, i am not getting expected results in ${line}1.txt.
For example, I have two UID like kplus , kplustp. what is my requirement is find "kplus" string from ps -elf command and create a file as same name like kplus.txt and redirect or move the data whatever found data using grep command.
But I am getting kplus and kplustp data in kplus.txt file. I need only kplus value based on UID column from ps –elf in kplus.txt file.
This is wrong way to read variable using awk
awk '{if($4 == "$line") print $0;}' $line.sh
Use:
awk '{if($4 == var) print $0;}' var="$line" $line.sh
Or shorten to
awk '$4==var' var="$line" $line.sh
default action is {print $0} if no action is specified.
If you need to search for the text $line escape the $ in regex
awk '$4==/\$line/' $line.sh
or in text it should work directly
awk '$4=="$line"' $line.sh

check if file is empty or not

How do I check if a file is empty in a korn script
I want to test in my korn script if the output CSV file is empty or not and if it is not empty then it should give the count of values.
Thanks.
The test(1) program has a -s switch:
-s FILE
FILE exists and has a size greater than zero
This is just another way of doing it, albeit a roundabout one:
if [ `ls -l <file> | awk '{print $5}'` -eq 0 ]
then
//condition for being empty
else
//condition for not being empty
fi
if [ ! -f manogna.txt ]
then
echo " Error: manogna.txt does not exist "
else
echo " manogna.txt exist "
echo " no of records in manogna.txt are `cat manogna.txt | wc -l`"
fi

Unix script to delete file if it contains single line

Consider I have a file abcde.txt which may contain one or more lines of text. I want a script that will DELETE the file if it contains single line.
Something like, if 'wc -l abscde.txt' = 1 then rm abscde.txt
My system : Solaris
Here's a simple bash script:
#!/bin/bash
LINECOUNT=`wc -l abscde.txt | cut -f1 -d' '`
if [[ $LINECOUNT == 1 ]]; then
rm -f abscde.txt
fi
delifsingleline () {
if [ $(cat $1 | wc -l) = "1" ]
then
echo "Deleting $1"
echo "rm $1"
fi
}
Lightly tested on zsh. Should work on bash as well.
This is (mostly) just a reformat of Ben's answer:
wc -l $PATH | grep '^1 ' > /dev/null && rm -f $PATH

Resources