grep exact integer match - bash

read -p "Please enter ID: " staffID
id=$(grep -w "$staffID" record | cut -d ":" -f1 | sort -u );
echo $id
I have some issues with trying to grep the correct value from a file.
The following is stored in the record file.
12:Griffin:Peter:13:14:16
14:Griffin:Meg:19:19:10
10:Griffin:Loi:19:20:20
130:Griffin:Stewie:19:19:19
13:Wayne:Bruce:19:20:2
My first column stores the id which is always unique and is what I am looking for in grep. With the code above, I only want to find the unique ID which is entered by a user and is displayed on screen but my echo produces a blank value if I enter an ID of 13 when it should produce 13 obviously. Any ideas which would solve this?

#!/bin/bash
read -p "Please enter ID: " staffID
#your code was commented out
#id=$(grep -w "$staffID" record | cut -d ":" -f1 | sort -u );
id=$(grep -oP "^${staffID}(?=:)" record)
line=$(grep "^${staffID}:" record)
echo $id #use this line if you just want ID
echo $line #use this line if you want the line with given ID
see comments in codes
Note
I don't know the exact requirement, but I suggest that before do grep, check user input, if they inputted a valid id ([0-9]+) maybe? Because user could input .*

Seems adding a ^ to grep should solve your problem.
read -p "Please enter ID: " staffID
[[ "$staffID" =~ ^[0-9]+$ ]] || { echo "Enter only Numbers. Aborting" ; exit 2 ; }
id=$(grep -w "^$staffID" record | cut -d ":" -f1 | sort -u );
if [ "$id" == "" ]; then
echo "ID : Not found"
else
echo $id
fi
I have added a line to check that your input is a valid number.

Related

BASH - Print new entry to file with line number included

I can't figure out how to add a line to a file then print that line only with the line number. Here is my current code which prints all lines:
printf "Would you like to add an entry to the file? Type yes or y? "
read addline
input=$addline
if [ $input = 'yes' ] || [ $input = 'y' ]
then
printf "Please enter a new name: First Last: "
read newname
printf "Please enter a new telephone number: xxx-xxx-xxxx: "
read phone
printf "Please enter a street address only: xxx Example Street: "
read street
printf "Please enter your birthdate: xx-xx-xxxx: "
read birth
printf "Please enter salary: xxxxxxx: "
read salary
echo -e "$newname:$phone:$street:$birth:$salary" >> datafile.txt
else
printf "\nYou did not type yes or y. Run the program again.\n"
exit
fi
printf "\nYour entry has been saved.\n"
sort -k2 $file | nl
You can use the -n option to grep to print a matching line along with its line number.
grep -n -F -x "$newname:$phone:$street:$birth:$salary" datafile.txt
Thanks to help from Barmar, I figured out my answer.
cat -n $file | grep "$newname:$phone:$street:$birth:$salary"
Thanks everyone.

if variable exists in col 1 of a file, set a separate variable equal to the corresponding value in col 2

I'm writing a script to run a grep for an input, create a file list and grep that file list in a separate directory and print the results.
echo "enter term"
read term
grep -rc "$term" /prod/directory1 | grep -v ":0" | sed -s 's%:[0-9]*%%' > file_list.txt
grep -rl --file=file_list.txt /tmp/directory2 > results.txt
but i would like to add an if statement that will identify if the $term is equal to a value in the first column of another file, and then set a new variable to the corresponding value in column 2 of that file.
echo "enter term"
read term
for i in products.txt; do
if [[ $term = $i ]]; then
var2 = $2
echo "product code set to: "$var2
else
var2 = 0
echo "product code set to 0."
fi
done
grep -rc "$term" /prod/directory1 | grep -v ":0" | sed -s 's%:[0-9]*%%' > file_list.txt
if [[ ! $var2 = 0 ]] ; then
grep -rc "var2" /prod/directory1 | grep -v ":0" | sed -s 's%:[0-9]*%%' >> file_list.txt
sed -s 's%.properties%%' file_list.txt | sort -u > file_list.txt
grep -rl --file=file_list.txt /tmp/directory2 > results.txt
the new grep will return results with .properties at the end, so I remove them and also any duplicate files from the list. Below is a sample for products.txt
Product_1 productCode_1
Product_2 productCode_2
Product_3 productCode_3
I would like the script to identify whether $term is in column one of that file, and then set $var2 equal to the corresponding productCode in column two. I believe once that variable is set everything else will work out nicely but right now it fails at:
for i in products.txt; do
if [[$term = $i ]]; then
var2 = $2
Thanks in advance for the assistance, I'm relatively new to bash scripting so I apologize in advance for my ineptitude.
Try:
var2=$(awk -v term="Product_2" '$1==term{print $2}' products.txt)
Change Product_2 to read from another variable, if required.

add specific string to a specific line at the end. -bash

I have a textfile(particulars.txt) which contains
personId,personName,employmentType
particulars.txt
1,jane,partTime
2,bob,fullTime
3,john,fullTime
How to do I make it such that if I key in the name of the worker, it will check whether that person is full time or part time worker and prompts the user to key in the salary and rewrite back to the file just for that person. I will explain in more details.
for example
Enter Name:jane
jane is a partTime staff
Enter Hourly Salary:10
so the textfile(particulars.txt) will now be
1,jane,partTime,10
2,bob,fullTime
3,johnfullTime
example two
Enter Name:bob
bob is a fullTime staff
Enter monthly Salary:1600
so the textfile(particulars.txt) will now be
1,jane,partTime,10
2,bob,fullTime,1600
3,john,fullTime
this is what I have
my code
#!/bin/bash
fileName="particulars.txt"
read -p "Enter name:" name
if grep -q $name $fileName; then
employmentType=$(grep $name $fileName | cut -d, -f4)
echo "$name is $employmentType" staff"
if [ $employmentType == "partTime" ]; then
echo "Enter hourly pay:"
read hourlyPay
#calculations for monthly salary(which I have not done)
elif [ $employmentType == "fullTime" ]; then
echo "Enter monthly salary:"
read monthlySalary
fi
else
echo "No record found"
fi
read -p "Press[Enter Key] to Contiune.." readEnterKey
I am only able to find which employment type does the person belongs to, but I am not sure of how/what should I do to add the salary at the end of the line just for that particular person. i have read up on sed , but I'm still confused on how to use sed to achieve my results and thus seeking help from you guys. Thanks in advance
Unless you need to do it in an interactive manner, you can say:
sed '/\bbob\b/{s/$/,1600/}' filename
This would add ,1600 to the line matching bob. Note that by specifying word boundaries \b, you'd ensure that the change is done only for bob, not abob or boba.
You can use the -i option to make the changes to the file in-place:
sed -i '/\bbob\b/{s/$/,1600/}' filename
EDIT: In order to use shell variable, use double quotes for the sed command:
sed "/\b$employeeName\b/{s/^$/,$monthlySalary/}" filename
I just modified your script.
#!/bin/bash
fileName="particulars.txt"
read -p "Enter name:" name
if grep -q $name $fileName; then
employmentType=$(grep $name $fileName | cut -d, -f3)
emp_name=$(grep $name $fileName | cut -d, -f2) # Getting emp name
emp_id=$(grep $name $fileName | cut -d, -f1) # Getting id
echo "$name is $employmentType staff"
if [ $employmentType == "partTime" ]; then
echo "Enter hourly pay:"
read hourlyPay
#calculations for monthly salary(which I have not done)
sed -i "s/^$emp_id.*$/&,$hourlyPay/g" $fileName # Modifying the file by using id.
elif [ $employmentType == "fullTime" ]; then
echo "Enter monthly salary:"
read monthlySalary
fi
else
echo "No record found"
fi
read -p "Press[Enter Key] to Contiune.." readEnterKey
I have added the below lines.
emp_id=$(grep $name $fileName | cut -d, -f1)
emp_name=$(grep $name $fileName | cut -d, -f2)
sed -i "s/^$emp_id.*$/&,$hourlyPay/g" $fileName

Command not found error

I've received an error command not found not sure what is wrong.
i think there is a problem with my code. i need user to enter the pay.
first user enter the ID, then the program will find the person with that ID.
then program will find the type of employee he is [salaried, or hourly]
then from there it will goes to if [$type="Salaried"] or' Hourly' code and
prompt user to key in the respective data
please advise how do i go about doing it?
payroll()
{
line=`grep -i "^${update_empID}," $data`
empID=`echo $line | cut -d "," -f1`
name=`echo $line | cut -d "," -f2`
job=`echo $line | cut -d "," -f3`
phone=`echo $line | cut -d "," -f4`
type=`echo $line | cut -d "," -f5`
clear
echo -e "Enter the pay"
echo -en "Enter ID: "
read empid_search
#Check if particular entry to search for existed to perform deletion
if [ `count_lines "^${empid_search},"` -eq 0 ]
then
echo "Error: This particular record does not exist!!"
else
echo "Please verify update of this employee's record: " #Prompt for confirmation of employee details
echo
echo "Employee's Details: "
locate_lines "^${empid_search}," #Find location of the entry
if [$type="Salaried"]
then
echo "$name is a Salaried"
echo "Enter Salary :"
read salary
echo "${empID},${name},${job},${phone},${Type},${salary}" >> tmpfile ; mv tmpfile $data
echo " particulars has been updated!!"
fi
else
echo "f"
fi
}
TEXT FILE
3,Frak,IT,9765753,Salaried
1,May,CEO,9789292,Salaried
5,Samy,Sales user,92221312,Commission
2,Orange,cleaner,935233233,Hourly
error:
line 371: [=Salaried]: command not found
This is the problem line:
if [$type="Salaried"]
You need to have spaces while comparing values in [ and ]:
if [ "$type" = "Salaried" ]

bash script and greping with command line

new to bash scripting so just wondering if i am doing this code right at all. im trying to search /etc/passwd and then grep and print users.
usage ()
{
echo "usage: ./file.sk user"
}
# test if we have two arguments on the command line
if [ $# != 1 ]
then
usage
exit
fi
if [[ $# < 0 ]];then
usage
exit
fi
# Search for user
fullname=`grep $1 /etc/passwd | cut -f 5 -d :`
firstname=`grep $1 /etc/passwd | cut -f 5 -d : | cut -f 1 -d " "`
#check if there. if name is founf: print msg and line entry
not sure as how to this or if im doing this right...
am i doing this right?
grep $1 /etc/passwd | while IFS=: read -r username passwd uid gid info home shell
do
echo $username: $info
done
This might work for you:
fullname=$(awk -F: '/'$1'/{print $5}' /etc/passwd)
firstname=${fullname/ *}
You're on the right track.
But I think the 2nd if [[ $# < 0 ]] .... fi block doesn't get you much. Your first test case gets the situation right, 'This script requires 1 argument or quits'.
Also, I don't see what you need firstname for, so a basic test is
case "${fullname:--1}" in
-[1] ) printf "No userID found for input=$1\n" ; exit 1 ;;
* )
# assume it is OK
# do what every you want after this case block
;;
esac
You can of course, duplicate this using "${firstname}" if you really need the check.
OR as an equivalent if ... fi is
if [[ "${fullname}" == "" ]] ; then
printf "No userID found for input=$1\n" ; exit 1
fi
note to be more efficient, you can parse ${fullname} to get firstname without all the calls to grep etc, i.e.
firstname=${fullname%% *}
Let me know if you need for me to explain :--1} and %% *} variable modifiers.
I hope this helps.
Instead of this:
fullname=`grep $1 /etc/passwd | cut -f 5 -d :`
firstname=`grep $1 /etc/passwd | cut -f 5 -d : | cut -f 1 -d " "`
Try this:
fullname=$(cut -f5 -d: /etc/passwd | grep "$1")
if [[ $? -ne 0 ]]; then
# not found, do something
fi
firstname=${fullname%% *} # remove the space and everything after
Note that I changed my answer to cut before grep so that it doesn't get false positives if some other field matches the full name you are searching for.
You can simply by reading your input to an array and then printing out your desired fields, something like this -
grep $1 /etc/passwd | while IFS=: read -a arry; do
echo ${arry[0]}:${arry[4]};
done
Test:
jaypal:~/Temp] echo "root:*:0:0:System Administrator:/var/root:/bin/sh" |
while IFS=: read -a arry; do
echo ${arry[0]}:${arry[4]};
done
root:System Administrator

Resources