1

to check if a word is in a list of words or no I wrote this script:

tr -s '[[:blank:]]' '\n' < t.txt |


while IFS= read -r word; do


if [[ "$word" =~ $(echo ^\($(paste -sd'|' ./champs.txt)\)$) ]]; then

but checking is not done. Even the word list was not checked any time

The file t.txt contains a list of sql query:

select * from student;
insert name, age, from professors;
delete from departement where DPTNUM= '20';

and the file champs.txt contains the query keywords

select
insert
into
values
delete
drop
from
create
table
where
set
varchar
number
  • can you paste the contents of t.txt and champs.txt and clarify what exactly are you trying to do? – rahul Apr 13 '15 at 10:13
  • I suspect it can be solved with a simple grep, but I would like to see an example of the contents of t.txt and champs.txt. – jcbermu Apr 13 '15 at 10:15
  • when i have to put the grep – Aomine Daiki Apr 13 '15 at 10:29
1

It is not very clear...

grep -owf champs.txt  t.txt
0

Your regex-building command is a little bit wrong; besides, it's very inefficient to rebuild the same pattern on every loop iteration.

Although bash has a read command it's generally discouraged to use it for processing large amounts of text, since it's very slow, as well as being a common source of scripting errors. So try to restrict the use of read to processing simple user input.

As others have mentioned, this is a job for grep. Or if you want more control, consider using awk, which has good regex abilities. But if you really want to do it in a way similar to your posted code, here's one way to do it.

#!/usr/bin/env bash

pat='^('$(paste -sd'|' champs.txt)')$'
printf "pattern: '%s'\n" "$pat"

IFS=
tr -s '[:blank:]' '\n' < t.txt |
while read -r word; do
    if [[ "$word" =~ $pat ]]; 
        then echo "'$word' in list"
        else echo "'$word' NOT in list"
    fi
done

(The above script passes ShellCheck analysis).

As you can see, we build the regex pattern pat outside the loop; I've added a printf to display the pattern so we can be sure it's what we want. Note that it's generally much better to use printf than echo to display arbitrary strings.

I've modified your t.txt to add a few extra test words, but used the same champs.txt as posted above.

t.txt

select * from student;
insert name, age, from professors;
delete from departement where DPTNUM= '20';
test number ins settle deleted

And here's the output:

pattern: '^(select|insert|into|values|delete|drop|from|create|table|where|set|varchar|number)$'
'select' in list
'*' NOT in list
'from' in list
'student;' NOT in list
'insert' in list
'name,' NOT in list
'age,' NOT in list
'from' in list
'professors;' NOT in list
'delete' in list
'from' in list
'departement' NOT in list
'where' in list
'DPTNUM=' NOT in list
''20';' NOT in list
'test' NOT in list
'number' in list
'ins' NOT in list
'settle' NOT in list
'deleted' NOT in list
  • thank you, but i used read because I must parse all the text file word by word, and check every word and if that is not the case then I want to run other commands on the desired word. – Aomine Daiki Apr 13 '15 at 17:17
  • @AomineDaiki. Understood, however you can do that more efficiently (and with more safety) using awk, which has great features for running shell commands. See this question for why using a shell loop to process text is considered bad practice, especially Stéphane Chazelas's answer. – PM 2Ring Apr 14 '15 at 7:20
  • i do not know how to use awk to parse a text file word by word can you give me the command line please – Aomine Daiki Apr 14 '15 at 7:39
  • @AomineDaiki: To learn how to use awk please consult its man page; there are also many free tutorials online. As with any language, it will take time to master it, but awk is a fairly small & simple language, and it shouldn't take you long to learn the basics. IMHO, awk is a lot more user-friendly than pure bash script, so it's a great addition to the skill set of any bash programmer. – PM 2Ring Apr 14 '15 at 8:23
  • @AomineDaiki: Here's a simple awk program that will print each whitespace-delimited word from one (or more) text files, with each word on a separate line. If no filenames are supplied on the commandline it will read from stdin. awk '{for(i=1; i<=NF; i++)print $i}' filename – PM 2Ring Apr 14 '15 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.