How to check return value of Find statment in shell script? - awk

How can I check the return value of "Find" statement in shell script
I am use Find in my script , if find statement don't find any file the execute exit !!
I want to check the return value of "Find" if it found any files or not

You can redirect output of the find command to a file called say output.txt then you can check if the size of that file is 0 or not by using -s option;
if [[ -s "output.txt" ]]
then
echo "File is not empty!"
else
echo "File is empty!"
fi

You can count the number of files found by find using the wc -l command:
export result=`find . -name *.txt | wc -l`
You can now check result to see how many files where found
if [ $result == "0" ]; then echo zero found; fi

Related

BASH script to create SQL statement ignore last column

I am trying to create a bash script that will generate an SQL CREATE TABLE statement from a CSV file.
#!/bin/bash
# Check if the user provided a CSV file
if [ $# -eq 0 ]
then
echo "No CSV file provided."
exit 1
fi
# Check if the CSV file exists
if [ ! -f $1 ]
then
echo "CSV file does not exist."
exit 1
fi
# Get the table name from the CSV file name
table_name=$(basename $1 .csv)
# Extract the header row from the CSV file
header=$(head -n 1 $1)
# Split the header row into column names
IFS=',' read -r -a columns <<< "$header"
# Generate the PostgreSQL `CREATE TABLE` statement
echo "CREATE TABLE $table_name ("
for column in "${columns[#]}"
do
echo " $column TEXT,"
done
echo ");"
If I have a CSV file with three columns(aa,bb,cc), the generated statement does not have the last column for some reason.
Any idea what could be wrong?
If I do:
for a in "${array[#]}"
do
echo "$a"
done
I am getting:
aaa
bbb
ccc
But when add something into the string:
for a in "${array[#]}"
do
echo "$a SOMETHING"
done
I get:
aaa SOMETHING
bbb SOMETHING
SOMETHING
Thanks.
Your csv file has a '\r`
Try the next block for reproducing the problem.
printf -v header "%s,%s,%s\r\n" "aaa" "bbb" "ccc"
IFS=',' read -r -a columns <<< "$header"
echo "Show array"
for a in "${columns[#]}"; do echo "$a"; done
echo "Now with something extra"
for a in "${columns[#]}"; do echo "$a SOMETHING"; done
You should remove the '\r', what can be done with
IFS=',' read -r -a columns < <(tr -d '\r' <<< "${header}")

Writing a script in Unix to see if a file exist and to show its content

I'm writing a program in Unix to have the user enter in the file they would like to view the contents on but i'm stuck and dont know way i keep getting error.
the errors i keep getting are :unexpected EOF while looking for matching `"'
and the other is: Syntax error: unexpected end of file
# this program allows the user to see the contents of a file
echo
clear
echo
echo "Enter in the the file you would like to see: "
read $1
if [ ! -e "$1" ]
then
echo cat /export/home/cna397/logname/$1
else
echo "This file does not exist
fi
You're missing an ending double quote here:
echo "This file does not exist
$1 is for commandline arguments. You'll need something like this if you want the user to enter a filename while the script is running:
read filename
echo $(cat "/export/home/cna397/logname/$filename")
this is the executable (without errors) version of what you wrote, now continue with a better basis, if you still have questions just update this post with code plus comments, or just make a new one.
echo "Enter in the the file you would like to see:"
read file_name
if test ! = $file_name
then
echo $(cat /export/home/cna397/logname/$file_name)
else
echo "This file does not exist"
fi
P.S if on the if test you are checking strings, keep the equal (=) i put....

How can i error out an entry if it already exists?

I'm writing a simple program to add a contact into a file called "phonebook", but if the contact already exists, i want it to return an echo saying " (first name last name) already exists", and not add it to the file. So far, i've gotten the program to add the user, but it wont return that echo and adds the duplicate entry anyway. How can i fix this?
#!/bin/bash
# Check that 5 arguments are passed
#
if [ "$#" -ne 5 ]
then
echo
echo "Usage: first_name last_name phone_no room_no building"
echo
exit 1
fi
first=$1
last=$2
phone=$3
room=$4
building=$5
# Count the number of times the input name is in add_phonebook
count=$( grep -i "^$last:$first:" add_phonebook | wc -l )
#echo $count
# Check that the name is in the phonebook
if [ "$count" -eq 1 ]
then
echo
echo "$first $last is already in the phonebook."
echo
exit 1
fi
# Add someone to the phone book
#
echo "$1 $2 $3 $4 $5" >> add_phonebook
# Exit Successfully
exit 0
Couple of things:
Should check if add_phonebook file exists before attempting to grep it, otherwise you get the grep: add_phonebook: No such file or directory output.
Your grep expression doesn't match the format of the file.
You are saving the file with space in between the fields, but searching with a colon(:) between the names. You can either update the file format to use a colon to separate the fields, or update the grep expression to search on space. In addition, you save first name, last_name, but search on last_name, first_name.
With space format:
count=$( grep -i "^$last[[:space:]]\+$first[[:space:]]" add_phonebook | wc -l )
Removed my tab separators from the echo line, used spaces, and now it can count properly

Can you make it so that a bash command runs under certain conditions only?

I'm trying to do something like this (logic wise) but it's not working:
if (ls | wc -l ) >100; echo "too many files!"
else ls;
the point is adding this to my bashrc.
Any ideas?
Just an edit because I think I was slightly misunderstood. What I want is that when I type ls (or an alias that runs a modified ls) anywhere the files are only listed when there aren't a lot of them (I want something to add to my .bashrc). Being a bit of a moron, I sometimes type ls in directories where I have thousands of files so I'd like a way to circumvent that.
Rather than parsing ls, which is not best practice, you can do this with a bash array:
files=(*)
if ((${#files[#]} > 100)); then echo 'Too many files!'; else ls; fi
Probably in the actual problem you want a specific directory, and not the CWD; in that case, you might want something like this:
files=(/path/to/directory/*)
if ((${#files[#]} > 100)); then
echo 'Too many files!'
else (
cd /path/to/directory
ls
)
fi
Note that I've wrapped the cd into a parenthesized compound command, which means that the cd will be local. That assumes that you don't actually want the full path to appear in the output of ls.
You can do using find:
numFiles=$(find . -maxdepth 1 ! -name . -print0 | xargs -0 -I % echo . | wc -l)
(( numFiles > 100 )) && echo "too many files!" || ls
You can make this as function and put it in .bashrc
As others have pointed out, this is not an accurate way to count the number of files you have. It will miscount files that contain newlines for example and can have other issues.
It is, however, a perfectly good way to count the number of lines that ls will print and not show them if they're too many which is what you're presumably trying to do.
So, to answer your general question, to make one command depend on the result of another, you can use one of
command1 && command2
That will run command2 only if command1 was successful. If you want the second to be executed only if the first's results pass some test you can use:
[ command1 ] && command2
For your example, that would be:
[ $(ls | wc -l) -gt 100 ] && echo too many
To also execute ls again if the test is passed, use either
[ $(ls | wc -l) -gt 100 ] && echo too || ls
or
if [ $(ls | wc -l) -gt 200 ]; then echo 'too many files!'; else ls; fi
However, all of these are inelegant since they need to run the command twice. A better way might be to run the command once, save its output to a variable and then test the variable:
x=$(ls); [ $(wc -l <<<"$x") -gt 100 ] && echo 'too many!' || printf "%s\n" "$x"
Here, the output of ls is saved in the variable $x, then that variable is given as input to wc and if it has more than 100 lines, a message is printed. Else, the variable is.
For the sake of completeness, here's another safe approach that will count files correctly:
[ $(find -maxdepth 1 | grep -cF './') -gt 100 ] && echo 'too many!' || ls
A quick one liner:
test `find . -maxdepth 1 -type f|wc -l` -gt 100 && echo "Too Many Files"
A short one
[ $(ls | wc -l ) -gt 100 ] && echo too many
Combining some of the responses above - a simple Alias:
alias chkls='MAX=100 ; F=(*) ; if [[ ${#F[*]} -gt ${MAX} ]] ; then echo "## Folder: $(pwd) ## Too many files: ${#F[*]} ##" ; else ls ; fi '

fish shell - Showing the current command in the window title of screen

I want the current command to be shown in the title of screen (or tmux).
I tried following settings but it doesn't work.
How can I make it work?
.screenrc
shelltitle "$ |fish"
shell /usr/local/bin/fish
.config/fish/config.fish
set -x PS1 '\033k\033\\[\u#\h \W]\$ '
For fish version 2.1.0 you only have to edit ~/.config/fish/functions/fish_title.fish
function fish_title
hostname
end
For version 1.23.1 this doesn't seem to work. If the directories do not exist, first create them:
mkdir -p ~/.config/fish/functions/
What worked for me in .config/fish/functions/fish_title.fish :
function fish_title
# this one sets the X terminal window title
# argv[1] has the full command line
echo (hostname): (pwd): $argv[1]
switch "$TERM"
case 'screen*'
# prepend hostname to screen(1) title only if on ssh
if set -q SSH_CLIENT
set maybehost (hostname):
else
set maybehost ""
end
# inside the function fish_title(), we need to
# force stdout to reach the terminal
#
# (status current-command) gives only the command name
echo -ne "\\ek"$maybehost(status current-command)"\\e\\" > /dev/tty
end
end
I think you're looking for fish_title. See documentation here.
You could do something like this:
function fish_title
echo $_ ' '
pwd
end
funcsave fish_title
(Note you just run this at a prompt - don't put it in a config file).
Thanks for your answers.
Finally, this made it work!
.screenrc
shelltitle "$ |fish"
shell /usr/local/bin/fish
.config/fish/config.fish
function fish_prompt
echo -ne '\033k'
echo -ne $argv
echo -ne '\033\\'
echo -ne '$ '
end