5

I am facing an issue of searching through lines of text in a text file.

Currently, I am using this command

check=`awk -F : -v "title=$title" 'tolower($1) ~ tolower(title)' test.txt`

It works fine when the strings are pure alphabetic characters. Assuming the text file contains 3 lines of string which are

C++ Programming in 21 Days
C## Programming in 21 Days
C Programming in 21 Days

When I do a partial search for just a letter C, 3 of the results will be displayed, which is what I want, however, if I keyed in C++ P, my program will return text not found. And if i key in C++, all 3 results will be displayed as well.

But the funny thing is, if I search for C## P, my program will return C## Programming in 21 Days found.

I can't seem to find out what is causing this error, please help.

2 Answers 2

5

tolower(title) is handled as regular expression:

  • C++ matches the character C literally (case sensitive)

    • Quantifier: ++ Between one and unlimited times, as many times as possible, without giving back [possessive]
  • C matches the character C literally (case sensitive)

  • C## matches the characters C## literally (case sensitive)

To get the right result for C++ you need the pattern C\+\+


Examples

% title="C\+\+"                                                
% awk -F : -v "title=$title" 'tolower($1) ~ tolower(title)' foo
C++ Programming in 21 Days

or shorter

% awk '/[Cc]\+\+/' foo 
C++ Programming in 21 Days

% awk '/[Cc]##/' foo  
C## Programming in 21 Days

% awk '/[Cc] /' foo
C Programming in 21 Days

or with an external variable

% title='C## P'
% awk '/'"$title"'/' foo   
C## Programming in 21 Days

% title='C\+\+ P'                        
% awk '/'"$title"'/' foo 
C++ Programming in 21 Days

% title='C\+\+ P'
% check=$(awk '/'"$title"'/' foo) 
% echo $check
C++ Programming in 21 Days

and so on

1
  • Wow! Why this isn't the accepted answer, I don't know!
    – Fabby
    Aug 13, 2015 at 18:08
1

The "+" is getting treated as a regular expression.

$ title="C++ P"
$ awk -F: -v "title=$title" 'tolower($1) ~ tolower(title)' test.txt
C Programming in 21 Days
$ title="C.. P"
$ awk -F: -v "title=$title" 'tolower($1) ~ tolower(title)' test.txt
C++ Programming in 21 Days
C## Programming in 21 Days

If you're only interested in matching the start, you could use

$ awk -F: -v "title=$title" 'tolower(substr($0,0,length(title))) == tolower(title)' test.txt

Or to match anywhere within the line

$ title="C"
$ awk -F: -v "title=$title" 'index(tolower($0),tolower(title))' test.txt
C++ Programming in 21 Days
C## Programming in 21 Days
C Programming in 21 Days
$ title="C++ P"
$ awk -F: -v "title=$title" 'index(tolower($0),tolower(title))' test.txt
C++ Programming in 21 Days
$ title="C## P"
$ awk -F: -v "title=$title" 'index(tolower($0),tolower(title))' test.txt
C## Programming in 21 Days
6
  • is there anyway i can do so that it would be treated as a literal character ? And if C++ P is entered, no result would be found.
    – Zac
    Jul 11, 2015 at 20:30
  • tried it, didn't work, even keying in a C doesn't return any result
    – Zac
    Jul 11, 2015 at 20:36
  • @Zac Steve is using gawk
    – A.B.
    Jul 11, 2015 at 20:45
  • it worked but this time it couldn't display the result, do i have to change my code that does the displaying as well, the code is awk -F : -v title="$title" 'BEGIN { OFS = ", "} tolower($1) ~ tolower(title) { printf "%s,%s,$%.2f,%s,%s\n", $1, $2, $3, $4, $5 }' test.txt I have $1~$5 for displaying other data that is attached to the title
    – Zac
    Jul 11, 2015 at 20:45
  • 1
    never mind, i changed the tolower, it works now, thank you very much
    – Zac
    Jul 11, 2015 at 20:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .