I have used the below content to fetch some values .
But the grep in the code is not showing any results.
#!/bin/bash
file=test.txt
while IFS= read -r cmd;
do
check_address=`grep -c $cmd music.cpp`
if [ $check_address -ge 1 ]; then
echo
else
grep -i -n "$cmd" music.cpp
echo $cmd found
fi
done < "$file"
Note : there are no carriage return in my text file or .sh file.
i checked using
bash -x check.sh
It is just showing
+grep -i -n "$cmd" music.cpp
Related
I have a text document that contains URL's was write in the same way:
https://google.com
https://youtube.com
This code should read strings and get the html status from each strings in file. So it can't find the URL, i guess
exec 0<$1 #(Where $1 is param to input the file)
while IFS='' read -r line
response=$(curl --write-out %{http_code} --silent --output /dev/null $line)
[[ -n "$line" ]]
do
echo "Text read from file: $line"
This code save as the HtmlStatus.sh
you can create file for example test.txt
text.txt : https://google.com
https://youtube.com
https://facebook.com
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
echo -n "Read Url : $line"
curl -I $line | grep HTTP
done < "$1"
this code return the html status code at the test.txt file line in url.
run terminal :
chmod +x HtmlStatus.sh
./HtmlStatus.sh test.txt
#!/bin/bash
set_bash_profile()
{
local bash_profile="$HOME/.profile"
if [[ -w $bash_profile ]]; then
if (grep 'MY_VAR' $bash_profile 2>&1); then
sed -i '/MY_VAR/d' $bash_profile
fi
echo "export MY_VAR=foo" >>$bash_profile
fi
}
set_bash_profile
Here is the first run:
bash-4.1$ ./set_bash.sh
No output --which is great! And cat shows export MY_VAR=foo was appended to the file. But when executing a second time, I want sed to silently edit $bash_profile without outputting the matching string, like it does here:
bash-4.1$ ./set_bash.sh
export MY_VAR=foo
You get the output from grep on grep 'MY_VAR' $bash_profile 2>&1. grep outputs the matched line in your profile:
export MY_VAR=foo
on stdout. The 2>&1 only forwards stderr to stdout. It's good to use -q option with grep. Also the subshell (...) around the grep is not needed. Try this:
#!/bin/bash
set_bash_profile()
{
local bash_profile="$HOME/.profile"
if [ -w $bash_profile ]; then
if grep -q 'MY_VAR' $bash_profile; then
sed -i '/MY_VAR/d' $bash_profile
fi
echo "export MY_VAR=foo" >>$bash_profile
fi
}
set_bash_profile
This question already has answers here:
How to iterate over arguments in a Bash script
(9 answers)
How do I parse command line arguments in Bash?
(40 answers)
Closed 5 years ago.
I am having problem allowing my script to take more than three arguments. My script will take commands like this, for example:
./myscript.sh -i -v -r filename
so far if it only takes two arguments plus filename:
./myscript.sh -i -v filename
If I run the full commands, [-i] [-v] [-r] it gives this errors...
"mv: invalid option -- 'r'
Try 'mv --help' for more information."
here is my code so far....
#!/bin/bash
dirfile='.trash'
verbose=
function helpfunction()
{
echo "=============== HELP COMMAND ============="
echo ""
echo "-h | --help"
echo "-i | --interactive"
echo "-v | --verbose"
echo "-r | --recursive"
echo ""
}
if [ $# -eq 0 ]; then
echo "no commands"
exit 1
fi
option="${1}"
case ${option} in
-h | --help)
helpfunction
exit
;;
#interactive -i or --interactive
-i) FILE="${*}"
echo "File name is $FILE"
echo -n "Do you want to remove this file (y/n)? "
read answer
if echo "$answer" | grep -iq "^y" ;then
mv $FILE $dirfile
fi
;;
#verbose -v or --verbose
-v) FILE="${*}"
if [ -f "$FILE" ]; then
-v $FILE
fi
;;
#recursive -r or --recursive
-r) FILE="${*}"
if [ -d "${*}" ]; then
rm -r "$FILE"
fi
;;
#unremove -u or --unremove
-u) FILE="${*}"
for file in $dirfile*;
do
if [[ -f $file ]]; then
echo "file found"
else
echo "File not found"
fi
done
;;
#list -l or --list
-l) FILE="${*}"
for entry in "$dirfile"/*
do
echo "$entry"
done
;;
*)
echo "`basename ${0}`:usage: [-f file] | [-d directory]"
exit 1 # Command to come out of the program with status 1
;;
esac
When you say
FILE="${*}"
You're taking all the remaining arguments as one string, and assigning that to FILE. You can see this by adding 'set -x' to the top of your script:
opus$ ./myscript.sh -i -v -r filename
+ '[' 4 -eq 0 ']'
+ option=-i
+ case ${option} in
+ FILE='-i -v -r filename'
+ echo 'File name is -i -v -r filename'
File name is -i -v -r filename
+ echo -n 'Do you want to remove this file (y/n)? '
Do you want to remove this file (y/n)? + read answer
y
+ grep -iq '^y'
+ echo y
+ mv -i -v -r filename
mv: invalid option -- 'r'
Try 'mv --help' for more information.
Saying $1 gives the first argument. After you discover that, you can use shift to load the next argument as $1, and cycle through them like that.
Alternatively, you could just use the builtin getops argument parser.
Joe
You are getting error at this line
mv $FILE $dirfile
Here is the execution of your script in debug mode.
bash -x ./myscript.sh -i -v -r test.txt
+ dirfile=.trash
+ verbose=
+ '[' 4 -eq 0 ']'
+ option=-i
+ case ${option} in
+ FILE='-i -v -r test.txt'
+ echo 'File name is -i -v -r test.txt'
File name is -i -v -r test.txt
+ echo -n 'Do you want to remove this file (y/n)? '
Do you want to remove this file (y/n)? + read answer
y
+ echo y
+ grep -iq '^y'
+ mv -i -v -r test.txt .trash
mv: invalid option -- 'r'
Try 'mv --help' for more information.
-r is not a valid argument for mv.
Update your script like FILE=$4
if you want -i -v -r as optional, you can extract the last argument following this Getting the last argument passed to a shell script
You can also use ${!#} for getting the last parameter.
I have a script which is checking a key in one file against a key in another to see if it exists in both. However in the script the grep never returns anything has been found but on the command line it does.
#!/bin/bash
# First arg is the csv file of repo keys separated by line and in
# this manner 'customername,REPOKEY'
# Second arg is the log file to search through
log_file=$2
csv_file=$1
while read line;
do
customer=`echo "$line" | cut -d ',' -f 1`
repo_key=`echo "$line" | cut -d ',' -f 2`
if [ `grep "$repo_key" $log_file` ]; then
echo "1"
else
echo "0"
fi
done < $csv_file
The CSV file is formatted as follows:
customername,REPOKEY
and the log file is as follows:
REPOKEY
REPOKEY
REPOKEY
etc
I call the script by doing ./script csvfile.csv logfile.txt
Rather then checking output of grep command use grep -q to check its return status:
if grep -q "$repo_key" "$log_file"; then
echo "1"
else
echo "0"
fi
Also your script can be simplified to:
log_file=$2
csv_file=$1
while IFS=, read -r customer repo_key; do
if grep -q "$repo_key" "$log_file"; then
echo "1"
else
echo "0"
fi
done < "$csv_file"
use the exit status of the grep command to print 1 or 0
repo_key=`echo "$line" | cut -d ',' -f 2`
grep -q "$repo_key" $log_file
if [ $? -eq 1 ]; then
echo "1"
else
echo "0"
fi
-q supresses the output so that no output is printed
$? is the exit status of grep command 1 on successfull match and 0 on unsuccessfull
you can have a much simpler version as
grep -q "$repo_key" $log_file
echo $?
which will produce the same output
My assignment is to write a Unix shell script that asks the user for the name of a directory, and then works exactly like find.
Here is what I have so far:
#!/bin/bash
dir_lister()
{
cd "$1"
echo "$1"
list=$(ls -l ${1})
nolines=$(echo "$list" | awk 'END{printf "%d",NF}')
if [ $nolines -eq 2 ]
then
echo "$1"
return
fi
filelist=$(echo "$list" | grep ^-.*)
dirlist=$(echo "$list" | grep ^d.*)
filename=$(echo "$filelist"| awk '{printf "%s\n",$NF}')
present=$(pwd)
echo "$filename"| awk -v pres=$present '{printf "%s/%s\n",pres,$0}'
dirlist2=$(echo "$dirlist" | awk '{printf "%s\n",$NF}')
echo "$dirlist2" | while IFS= read -r line;
do
nextCall=$(echo "$present/$line");
dir_lister $nextCall;
cd ".."
done
cd ".."
}
read -p "Enter the name of the direcotry: " dName
dir_lister $dName
The problem is, after a depth of three directories, this script gets into an infinite loop, and I don't see why.
EDIT:
Here is the code i came up with after looking at your answer, it still doesn't go more than 1 directory depth:
#!/bin/bash
shopt -s dotglob # don't miss "hidden files"
shopt -s nullglob # don't fail on empty directories
list_directory()
{
cd "$2"
cd "$1"
##echo -e "I am called \t $1 \t $2"
for fileName in "$1/"*
do
##echo -e "hello \t $fileName"
if [ -d "$fileName" ];
then
echo "$fileName"
list_directory $fileName $2
else
echo "$fileName"
fi
done
}
read -p "Enter the direcotory Name: " dirName
var=$(pwd)
list_directory $dirName $var
Okay, that is completely the wrong way to list files in a directory (see ParsingLs). I'll give you the pieces and you should be able to put them together into a working script.
Put this at the top of your script:
shopt -s dotglob # don't miss "hidden files"
shopt -s nullglob # don't fail on empty directories
Then you can easily loop over directory contents with:
for file in "$directory/"* ; do
#...
done
Test if you have a directory:
if [ -d "$file" ] ; then
# "$file" is a directory, recurse...
fi