Using While and Grep together in Bourne Shell Script - grep

I'm building a student database in Bourne Shell Script, and this is literally the very first time I've ever even seen code written like this, so I'm terribly out of my element. I need to make it so that when the user inputs a course, the program checks the user input vs a database of courses I already have, and if the course doesn't exist, promps the user to input a new course. This is what I'm trying:
echo "course-1: \c"
read course1
while [[ grep -i "$course1" course3.dat == 1]]
do
echo "course does not exist"
echo "course-1: \c"
read course1
done
echo "course-2: \c"
read course2
while [[ grep -i "$course2" course3.dat == 1]]
do
echo "course does not exist"
echo "course-2: \c"
read course2
done
But I'm getting errors "conditional binary operator expected" and "syntax error near `-i' ". I've been trying to google answers but I'm not coming up with anything useful. So I was wondering if any of you could help me? Thanks so much.

[[ is a shortcut for /bin/test, which isn't what you want. (Here's a man page about it.)
Try this instead:
while ! grep -i "$course1" course3.dat
Or
until grep -i "$course1" course3.dat
The grep expression evaluates to true when grep is successful (i.e. matching lines), and the ! inverts that. Until has built in the opposite semantics from while.

[[ and [ are "test", which is what you want.
However, different shells have different syntaxes; ksh or bash would interpret "[[" okay, but Bourne shell (normally /bin/sh) would not.

Related

using grep command to get spectfic word [LINUX]

I have a test.txt file with links for example:
google.com?test=
google.com?hello=
and this code
xargs -0 -n1 -a FUZZvul.txt -d '\n' -P 20 -I % curl -ks1L '%/?=DarkLotus' | grep -a 'DarkLotus'
When I type a specific word, such as DarkLotus, in the terminal, it checks the links in the file and it brings me the word which is reflected in the links i provided in the test file
There is no problem here, the problem is that I have many links, and when the result appears in the terminal, I do not know which site reflected the DarkLotus word.
How can i do it?
Try -n option. It shows the line number of file with the matched line.
Best Regards,
Haridas.
I'm not sure what you are up to there, but can you invert it? grep by default prints matching lines. The problem here is you are piping the input from the stdout of the previous commands into grep, and that can lack context at grep. Since you have a file to work with:
$ grep 'DarkLotus' FUZZvul.txt
If your intention is to also follow the link then it might be easier to write a bash script:
#!/bin/bash
for line in `grep 'DarkLotus FUZZvul.txt`
do
link=# extract link from line
echo ${link}
curl -ks1L ${link}
done
Then you could make your script accept user input:
#/bin/bash
word="${0}"
for line in `grep ${word} FUZZvul.txt`
...
and then
$ my_link_getter "DarkLotus"
https://google?somearg=DarkLotus
...
And then you could make the txt file a parameter.
etc.

How can i make grep show a line ignoring the words i want?

I am trying to use grep with the pwd command.
So, if i enter pwd, it shows me something like:
/home/hrq/my-project/
But, for purposes of a script i am making, i need to use it with grep, so it only prints what is after hrq/, so i need to hide my home folder always (the /home/hrq/) excerpt, and show only what is onwards (like, in this case, only my-project).
Is it possible?
I tried something like
pwd | grep -ov 'home', since i saw that the "-v" flag would be equivalent to the NOT operator, and combine it with the "-o" only matching flag. But it didn't work.
Given:
$ pwd
/home/foo/tmp
$ echo "$PWD"
/home/foo/tmp
Depending on what it is you really want to do, either of these is probably what you really should be using rather than trying to use grep:
$ basename "$PWD"
tmp
$ echo "${PWD#/home/foo/}"
tmp
Use grep -Po 'hrq/\K.*', for example:
grep -Po 'hrq/\K.*' <<< '/home/hrq/my-project/'
my-project/
Here, grep uses the following options:
-P : Use Perl regexes.
-o : Print the matches only (1 match per line), not the entire lines.
\K : Cause the regex engine to "keep" everything it had matched prior to the \K and not include it in the match. Specifically, ignore the preceding part of the regex when printing the match.
SEE ALSO:
grep manual
perlre - Perl regular expressions

grep : to look up a valid entry in a log

Hello everyone I'm having an issue with this script. I've just begun work on it and it is supposed to look for entries previously generated by another script I made.
The gist of the thing is that the log has entries like:
makefile_1786878:/home/user/project
the format is filename_inode:/originaldirectory/
and this script is supposed to take a parameter and look for its exact match in the log
if [ $# -eq 0 ]
then
echo "No filename has been provided. Please enter a filename to restore!"
exit 1
fi
echo You have entered $1
echo Looking for $1 in the list of items deleted by safe_rm...
restoredfile=$(grep ^$1 $HOME/.restore.info)
echo $restoredfile
The problem I'm having is, if the user entered "mak" or "make" or "makefi" as a parameter it will incorrectly look up this entry
I want it to specifically get the exact match for this, I don't know how to force grep to do that
Try either one of these and see if it'll work for you:
grep -w "makefile"
grep "\<makefile\>"
If that work, then just change your grep to:
grep either one of those with the $1 parameter inside.

egrep in python

so thanks to this forum, I currently have this code, which takes an output from a programme I have and saves it in a file:
#!usr/bin/python
import os
os.chdir('./P574/J0998-1034')
os.system('vap -c freq *.SFTC > 1400list.txt')
I wanted to add a filter (so take only lines that contained "1369.000", so I amended the last line to:
os.system('vap -c freq *.SFTC | egrep 1369.000 > 1400listfilt.txt')
But I really want it to take lines that contain EITHER "1369.000" OR "1433.000". I tried:
os.system('vap -c freq *.SFTC | egrep 1369.000|1433.000 > 1400listfilt.txt' )
But I got the error message: "sh: 1433.000: command not found
egrep: write error: Broken pipe"
How can I make it check for two values? Also.. is this the best way to do what I am trying to do?
Thank you!
I would surround the arguments in single quotes as such:
egrep '(1369.000|1433.000)'
The shell is telling you that it could not redirect the output of egrep to the program 1433.000 which doesn't exist.

How can I remove duplicates (deduplicate) a mbox format email mailbox?

I've got a mbox mailbox containing duplicate copies of messages, which differ only in their "X-Evolution:" header.
I want to remove the duplicate ones, in as quick and simple a way as possible. It seems like this would have been written already, but I haven't found it, although I've looked at the Python mailbox module, the various perl mbox parsers, formail, and so forth.
Does anyone have any suggestions?
This a small script, which I used for it:
#!/bin/bash
IDCACHE=$(mktemp -p /tmp)
formail -D $((1024*1024*10)) ${IDCACHE} -s
rm ${IDCACHE}
The mailbox needs to be piped through it, and in the meantime it will be deduplicated.
-D $((1024*1024*10)) sets a 10 Mebibyte cache, which is more than 10x the amount needed to deduplicate an entire year of my mail. YMMV, so adjust it accordingly. Setting it too high will cause some performance loss, setting it to low will let it slip duplicates.
formail is part of the procmail utility bundle, mktemp is part of coreutils.
I didn't look at formail (part of procmail) in enough detail. It does have such such an option, as mentioned in places like: http://hints.macworld.com/comment.php?mode=view&cid=115683 and http://us.generation-nt.com/answer/deleting-duplicate-mail-messages-help-172481881.html
'formail -D' and 'reformail -D' can only process one email per execution. Each mail needs to be separated from mbox first before being processed. I use reformail from maildrop instead since it's still in active development.
remove old idcache, tmpmail, nmbox
run dedup.sh .
nmbox is the output with duplicate messages removed.
dedup.sh
#! /bin/sh
# $1 = mbox, thunderbird mailbox
# wmbox.sh is called for each mail.
cat $1 | reformail -s ./wmbox.sh
wmbox.sh
#! /bin/sh
# stdin: a email
# called by dedup.sh
TM=tmpmail
if [ -f $TM ] ; then
echo error!
exit 1
fi
cat > $TM
# mbox format, each mail end with a blank line
echo "" >> $TM
cat $TM | reformail -D 99999999 idcache
# if this mail isn't a dup (reformail return 1 if message-id is not found)
if [ $? != 0 ]; then
# each mail shall have a message-id
if grep -q -i '^message-id:' $TM; then
cat tmpmail >> nmbox
fi
fi
rm $TM

Resources