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
Related
!#/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.
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
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
i tried to run this script :
for line in $(cat song.txt)
do echo "$line" >> out.txt
done
running it on ubuntu 11.04
when "song.txt" contains :
I read the news today oh boy
About a lucky man who made the grade
after running the script the "out.txt" looks like that:
I
read
the
news
today
oh
boy
About
a
lucky
man
who
made
the
grade
is anyone can tell me what i am doing wrong here?
For per-line input you should use while read, for example:
cat song.txt | while read line
do
echo "$line" >> out.txt
done
Better (more efficient really) would be the following method:
while read line
do
echo "$line"
done < song.txt > out.txt
That's because of the for command that takes every word from the list it is given (in your case, the content of the song.txt file), whether the words are separated by spaces or newline characters.
What's misguiding you here, is that your for variable name is line. for only works with words. Reread your script changing line by word and it should make sense.
In the for-each-in loop the list that is specified is assumed to be white-space separated. A white-space includes a space, new-line, tab etc. In your case the list is the entire text of the file and hence, the loop runs for every word in the file.
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.