how to update a file with info from standard input (keyboard) with shell script? - linux

Basically what I have to do is this:
I have a file containing names of students and their partial grades:
(firstname lastname grade)
And what I have to do is update that file with their exam grades and their final grades:
(partial+exam)/2
The exam grades are introduced via the keyboard. So I have to echo a student's name and read his exam grade from the keyboard, and update his line within the file, then move on to the next one, and when I'm all done sort it after the final grade column.
I'm stuck at reading the exam grade from the keyboard. I've tried using some form of awk and sed but cant get it to work (cant get the info from the keyboard) and I'm not even sure if thats how it has to be done.
Please help.
ty in advance,
bando
edit:
(ty for editing, im a bit new to this)
input looks like this:
Tom Green 7
Jenny Patricks 6
Andrew Gibbs 3
Collin Matthews 10
it has to run from a script. while running it should put to standard output the first and last name of a student and ask for his grade. once given it edits the file to look like:
Tom Green 7 9 8
and then steps to the next student.

This script does something similar you want:
#!/bin/bash
# $1 input file
# $2 output file (or equal to $1 if ommitted)
if [ -z "$2" ]; then
OUTFILE=$1
else
OUTFILE=$2
fi
cat $1 | while read -u 0 FIRST LAST PART ; do
echo "firstname: '$FIRST'"
echo "lastname: '$LAST'"
echo "grade: '$PART'"
read -p "Exam grade: " -u 1 EXAM
#Edit
# was let FINAL=(PART+EXAM)/2
# should be:
FINAL=$(calc \($PART+$EXAM\)/2)
echo "$FIRST $LAST $PART $EXAM $FINAL" >> tmp
echo "final grade: '$FINAL'"
echo -e "-----------\n"
done
mv tmp $OUTFILE
But the shell arithmetic is integer only. For dividing you have two operators: / (integer division) and % (reminder). I think you should consider other language for the task like python or perl.
Edit:
You may want to use the calc command from the apcalc. See the corrected script above. You'll have to tweak the calc command options to prevent it from taking over STDIN. Sorry I have to leave you with that - I have no time right now.

cat > will read from keyboard to wherever you like - press ctrl+D to close input.

You can use the read command to get user input from the user in shell script. For example
read data
echo $data.

Related

I would like to add 2 random numbers on the end of each username created from a file. How would I do this in bash?

!#/bin/bash
echo "which list of names would you like to add?"
read file
USER_LIST="(cut -d " " -f 1,2,3 $file --output-delimeter='.') "
echo "$USER_LIST | while read user; do echo "useradd "$user"";
done
using userlist.txt
james bond
ben afflack
john stewart
abdul rahim muhammad
CURRENT OUTPUT
james.bond
ben.afflack
john.stewart
abdul.rahim.muhammad
desired output
james.bond22
ben.afflack13
john.stewart11
abdul.rahim.muhammad83
What would be the easiest way to add the numbers to the end? I was looking at doing something along the lines of .$((RANDOM%10)).$((RANDOM%10))
any help is much appreciated. Thank you
You're on the right track with using $RANDOM, however its easier than you think. I was able to do it with the following:
user=james.bond
rand=${RANDOM:0:2}
if [ ${#rand} -lt 2 ]
then
rand=0$rand
fi
user=$user$rand
This sets user to james.bond23 (or some other 2 digit number). You just use parameter expansion to pick out the first two numbers generated by $RANDOM.
Refering to your question on how to implement this in a loop I have added a small snippet without using cut.
Assuming you have the file userlist.txt with the following content
james bond
ben afflack
john stewart
abdul rahim muhammad
In this file each name is seperated by a new line (\n).
The reading can be done with a single while loop. With the following quick approach you are able to print the desired the output:
#!/bin/bash
echo "which list of names would you like to add?"
# Read your file
read file
echo "Reading $file."
# Iterating trough each line of your text file.
while read p; do
# Accessing each element with $p: e. g. echo $p
# Apply a string manipulation on $p, add a
# random number at the end and print it out
echo ${p// /.}.${RANDOM:0:2}
done < $file # Your filename of your text file
The part ${p// /.} is called bash string manipulation. If you are interested in this, you can take a look at Shell-Parameter-Expansion. But it's not specified by POSIX. Not all Unix shells implement it.

How to retrieve all code between two words in shell?

I need your help.
I have a text file with many lines and for each line i want to extract a code.
This code is betwwen two pattern :
1) "quarantine"
2) ","
Exemple of my log.txt :
George Thibault give two balls quarantine: x27041992, to someone
Edward Thin give three PC'S quarantine : m5405051993, to Fed
Tommy Dijoux give one shoe quarantine : cD001252000, to luc
Wanted result in new file :
x27041992
m5405051993
cD001252000
Someone can help me please ?
Try using the following bash script
#!/bin/bash
>output
while read line; do
for word in $line; do
if [[ $word == *","* ]]; then
echo ${word::-1} >> output
fi
done
done < gr
Note: Using shell loop to process text file is not a good practice.
read this
Match the substring between quarantine and the first ,, and replace everthing with the remembered string.
When you alse wont to delete a :, change this command.
sed 's/.*quarantine\([^,]*,.*/\1/' log.txt

Line from bash command output stored in variable as string

I'm trying to find a solution to a problem analog to this one:
#command_A
A_output_Line_1
A_output_Line_2
A_output_Line_3
#command_B
B_output_Line_1
B_output_Line_2
Now I need to compare A_output_Line_2 and B_output_Line_1 and echo "Correct" if they are equal and "Not Correct" otherwise.
I guess the easiest way to do this is to copy a line of output in some variable and then after executing the two commands, simply compare the variables and echo something.
This I need to implement in a bash script and any information on how to get certain line of output stored in a variable would help me put the pieces together.
Also, it would be cool if anyone can tell me not only how to copy/store a line, but probably just a word or sequence like : line 1, bytes 4-12, stored like string in a variable.
I am not a complete beginner but also not anywhere near advanced linux bash user. Thanks to any help in advance and sorry for bad english!
An easier way might be to use diff, no?
Something like:
command_A > command_A.output
command_B > command_B.output
diff command_A.output command_B.output
This will work for comparing multiple strings.
But, since you want to know about single lines (and words in the lines) here are some pointers:
# first line of output of command_A
command_A | head -n 1
The -n 1 option says only to use the first line (default is 10 I think)
# second line of output of command_A
command_A | head -n 2 | tail -n 1
that will take the first two lines of the output of command_A and then the last of those two lines. Happy times :)
You can now store this information in a variable:
export output_A=`command_A | head -n 2 | tail -n 1`
export output_B=`command_B | head -n 1`
And then compare it:
if [ "$output_A" == "$output_B" ]; then echo 'Correct'; else echo 'Not Correct'; fi
To just get parts of a string, try looking into cut or (for more powerful stuff) sed and awk.
Also, just learing a good general purpose scripting language like python or ruby (even perl) can go a long way with this kind of problem.
Use the IFS (internal field separator) to separate on newlines and store the outputs in an array.
#!/bin/bash
IFS='
'
array_a=( $(./a.sh) )
array_b=( $(./b.sh) )
if [ "${array_a[1]}" = "${array_b[0]}" ]; then
echo "CORRECT"
else
echo "INCORRECT"
fi

Use bash script to read numbers

Write a bash script that will read 10 integers from users and append the output to a file ‘XYZ’. You are not allowed to use the ‘read’ statement more than once in the script.
#! /bin/bash
for i in {0,1,2,3,4,5,6,7,8,9}
do
read "i"
echo "0,1,2,3,4,5,6,7,8,9" >> XYZ
done
I am a student just bengin to learn this, I feel it is difficult, could you give me some suggestions? I think this should have many problems. Thank you very much.
Let's see what you already have. Your for loop does 10 iterations of a read command, and read appears only once in the script. You also append (>>) your output to the file XYZ.
You shouldn't use the same variable for loop counter and reading the input, though. And the sequence could be shortened to {0..9}.
What you're still missing is a condition to check that the user input actually is an integer. And you're probably supposed to output the value you read, not the string "0,1,2,3,4,5,6,7,8,9".
On a more general note, you may find the following guides helpful with learning bash:
Bash Guide for Beginners
Advanced Bash Scripting Guide
#!/bin/bash
echo 'Input 10 integers separated by commas:'
read line
nums=`echo -n "$line" | sed "s/,/ /g"`
for i in $nums; do
echo "$i" >> XYZ
done
If you input 9,8,7,6,5,4,3,2,1,0, those numbers will be appended to the XYZ file, each one in a new line.
Read 10 (or less,or more) integers into an array, output not more than the first 10:
read -p '10 integers please: ' -a number
IFS=,
echo "${number[*]:0:10}" >> XYZ
Input:
1 2 3 4 5 6 7 8 9 0
Output, comma separated:
1,2,3,4,5,6,7,8,9,0

Using bash to edit text file and display output

I have a text file with courses that looks like this:
csc 4567 - Computer Programming
This course is about stuff...blah blah blah
4.0000 credit hours
I need to write a bash script that takes the text file and extracts the necessary information to display course number, course name, course credit hours. No spaces, just commas between. Course credit hours as whole number.
I can extract the information using command line but I am lost when writing the bash script. I am guessing I should be using the grep and sed with bash? I'm not sure. This is what I have (which is obviously not anywhere near correct). Any advice would be appreciated.
while read courses.txt
do
$courseLine=grep -iE '^csc [0-9]{4}'
$creditHours=grep -iE '^[0-4]'
$courseNumber=${courseLine#/s/s*}
$courseName=${courseLine%/s/s*}
printf "$courseNumber,$courseName,$creditHours"
done
Above what I am trying to accomplish is: read the file line
save "csc 4567 - Comp prog" as course line
save "4" as credit hours
save everything left of second space in course line as course number
save everything right of second space in course line as course name
then display my desired output.
It should print csc4567,Computer Programming,4
And yes, this is homework, but since I am new to the forum it won't let me tag the post as such.
#/bin/bash
while read line
do
if [[ $line =~ ^(csc\ [0-9]+)\ \-(.*)+ ]]; then
a="$a${BASH_REMATCH[1]},${BASH_REMATCH[2]}"
elif [[ $line =~ ^([0-9]+)([0-9\.\,])+\ credit ]]; then
a="$a,${BASH_REMATCH[1]}\n"
#else
# a="$a,$line"
fi
done < "a1.txt"
echo -e $a

Resources