How to create a shell script that can scan a file for a specific word? - linux

one of the questions that I have been given to do for my Computer Science GCSE was:
Write a shell script that takes a string input from a user, asks for a file name and reports whether that string is present in the file.
However way I try to do it, I cannot create a shell script.
I don't need you to tell me the whole number, however, I have no idea where to start. I input the variable and the file name, however, I have no idea how to search for the chosen word in the chosen file. Any ideas?

Using grep can get this working, for example
viewEntry()
{
echo "Entering view entry"
echo -n "Enter Name: "
read input
if grep -q "$input" datafile
then
echo ""
echo -n "Information -> "
grep -w "$input" datafile
echo ""
else
echo "/!\Name Not Found/!\\"
fi
echo "Exiting view entry"
echo ""
}
dataFile is the file you would be reading from. Then making use of -q and -w arguments of grep, you should be able to navigate your chosen file.
This site does a great job explaining grep and your exact problem: http://www.cyberciti.biz/faq/howto-use-grep-command-in-linux-unix/

The following shell-script is a very quick approach to do what you suggested:
#!/bin/sh # Tell your shell with what program this script should be exectued
echo "Please enter the filename: "
read filename # read user input into variable filename
count=`grep -c $1 $filename` # store result of grep into variable count
if [ $count -gt 0 ] # check if count is greater than 0
then
echo "String is present:" $1
else
echo "String not found:" $1
fi
You should look at some tutorials to get the basics of shell-scripting. Your task isn't very complex, so after some reading you should be able understand what the script does and modify it according your needs.

Related

shell prompt not showing up after running a script

as per http://linuxcommand.org/lc3_wss0150.php i am trying to run this script
#!/bin/bash
# Program to print a text file with headers and footers
TEMP_FILE=./printfile.txt
pr $1 > $TEMP_FILE
echo -n "Print file? [y/n]: "
read
if [ "$REPLY" = "y" ]; then
less $TEMP_FILE
fi
but when i run it via
./print_demo.bash
which is what it is saved as in my bin directory, it does not echo "Print file? [y/n]:" and also does not return the shell prompt. i have to ctrl^c to get it back.
That script is expecting input.
pr "$1" > $TEMP_FILE
The $1 represents the first argument from the command line
./print_demo.bash <printable_filename_here.txt>

BASH grep script

I am trying to work on a bash script that checks for a username in the argument of the script and then outputs the relevant lines from the /etc/passwd and /etc/group files (not the /etc/shadow file). Currently, I am utilizing a if then else loop to check the contents of the /etc/* directory and output the relevant information. My intention was to output simple text line if a match user is not found in the two files, thus a null value. However, it is outputting information that is totally incorrect for what I am looking for.As a new user to BASH, and linux is general, I am sure there are some glaring issues right away. However, I am trying to learn.
Any help with the code of my script or a point in the right direction would be greatly appreciated. Thank you.
#! /bin/bash
USERLOOK='grep -h $USERID ~/etc/* | grep :x:'
grep $1 ~/etc/*
if [ -z $1 ]; then
echo "User not found."
else
echo "$USERLOOK"
fi
exit 0
Finds any lines in /etc/passwd or /etc/group that contain the inputted username:
#!/bin/bash
USERLOOK=$(grep -h "$1" /etc/passwd /etc/group)
if [ -z "$1" ] || [ -z "${USERLOOK}" ]; then
echo "User not found."
else
echo "$USERLOOK"
fi
I want to have the script function where I input ./script
user_to_check. If the username is found, I want to output all lines
where it was found... However, if the username was not found, I wanted
to echo that.
It can be as simple as
#!/bin/bash
grep "^${1}:" /etc/passwd /etc/group
[ $? -ne 0 ] && echo "User : ${1} not found"
As the user name appears in the beginning in both /etc/passwd & /etc/group we placed a ^ in grep to match stuff at beginning and by tradition a : appears just after the username.
Run the script as
./script 'username'
Stop, you're thinking about this all wrong.
A UNIX shell is an environment from which to call UNIX tools with a language to sequence those calls, that is all. The general purpose UNIX tool to manipulate text is awk. So if you need to look for text in a file and have control logic to do anything with it, that should be an awk script, not a shell script. Shells role is to just call awk, something like this:
awk -v user="$1" '
$0 ~ user { line = $0 }
END { print (line != "" ? line : "User not found") }
' /etc/passwd /etc/group
but note that it's trivial with awk to focus the search on just one field, even a different field for each file, unlike how difficult that is in general with grep.

Create parameters for command Linux shell script

Hello I am trying to create parameters for my shell script but I am having trouble.
lets say for example the file is called test.
When I call ./test -parameter1 input_file.txt
I get an error saying 'no such file or directory'.
Here is an example of my code.
#!/bin/sh
if [ "$1" == "parameter" ]
then
while read line
do
#echo "$line"
done <$1
else
echo "Not working"
fi
My over all goal of this is to read in a file of numbers line by line which I have working, then to calculate the average values of the rows or by columns. Which is why I am trying to create parameters so the user will have to specify ./test -rows input_file.txt or ./test -columns input_file.txt
You are using the string -parameter as the input file name. Perhaps you want:
#!/bin/sh
if [ "$1" = "-parameter" ]
then
while read line
do
#echo "$line"
done <$2 # Use $2 instead of $1 here. Or use shift
else
echo "Not working" >&2
fi

Smarter and more condensed method to match input variable in shell script?

I have a file with a list of numerous unique items, for this example I am using user ID's. The starting section of my script should display the list to the user running the script and allow them to chose one of the ID's. The script should then cross check the choice made by the user against the original file and if it matches it should provide a message advising of the match and continue with the script. If it does not match, the script should advise the user and exit.
My current script does this OK, but I was wondering if there is any way to make it a bit smarter/more condensed, perhaps using arrays? Current script:
This is my first post on this site so I apologies in advanced for any mistakes which have been made in the process of posting.
FILE=testfile
IDLIST="$(awk '{print $1}' $FILE)"
echo "$IDLIST"
echo "\nSelect one of the options"
read input
OUTPUT="$(for i in $IDLIST
do
if [[ $i = $input ]]
then
echo "Matched."
fi
done)"
if [[ -z $OUTPUT ]]
then
echo "Invalid choice."
exit 0
else
ID=$input
fi
echo "It is a match, continuing with script"
As you can imagine, there are many ways of doing this. One is using select instead:
PS3="Select an ID: "
select id in $(cut -d ' ' -f 1 testfile)
do
[[ -z $id ]] && echo "Pick a number" || break
done
echo "You selected $id"

How to open an editor from a bash function?

I have a simple function to open an editor:
open_an_editor()
{
nano "$1"
}
If called like open_an_editor file.ext, it works. But if I need to get some output from the function — smth=$(open_an_editor file.ext) — I cannot see the editor, script just stucks. What am I missing here?
Update: I am trying to write a function which would ask the user to write a value in editor, if it wasn't given in script arguments.
#!/bin/bash
open_an_editor()
{
if [ "$1" ]
then
echo "$1"
return 0
fi
tmpf=$(mktemp -t pref)
echo "default value, please edit" > "$tmpf"
# and here the editor should show up,
# allowing user to edit the value and save it
# this will stuck without showing the editor:
#nano "$tmpf"
# but this, with the help of Kimvais, works perfectly:
nano "$tmpf" 3>&1 1>&2 2>&3
cat "$tmpf"
rm "$tmpf"
}
something=$(open_an_editor "$1")
# and then I can do something useful with that value,
# for example count chars in it
echo -n "$something" | wc -c
So, if the script was called with an argument ./script.sh "A value", the function would just use that and immediately echo 7 bytes. But if called without arguments ./script.sh — nano should pop up.
If the input you need is the edited file, then you obviously need to cat filename after you do the open_an_editor filename
If you actually need the output of the editor, then you need to swap stderr and stdin i.e:
nano "$1" 3>&1 1>&2 2>&3
If yo need 'friendly' user input, see this question on how to use whiptail
if you need to get output from function and store in variable, you just display what's in file.
open_an_editor()
{
cat "$1"
}
smth=$(open_an_editor file.txt)
If all you want is for a user to enter a value then read is enough:
OLDIFS="$IFS"
IFS=$'\n'
read -p "Enter a value: " -e somevar
IFS="$OLDIFS"
echo "$somevar"

Resources