Input File My .txt file contains these kind of content :

Tom Thatcher's Fortune, by Horatio Alger, Jr.                   56896
Paradise Lost, by John Milton                                      20

The first string is book name,second is author and the last one is book number. I want to print the whole line when someone search for the book number (if the book number matches). I'm new to bash scripting.


Something like

grep BOOKNUMBER textfile.txt

should solve this.

If you want to avoid that searching for book number 96 also lists Tom Thatcher's Fortune you can use

grep '[[:space:]]BOOKNUMBER[[:space:]]*$' textfile.txt


As a script (save as searchbook)



if [[ -z "$BOOK" ]]; then 
    echo -n "Booknumber? "
    read BOOK

grep '[[:space:]]'$BOOK'[[:space:]]*$' $BOOKFILE

You can then either run

searchbook BOOKNUMBER



In the second case you will get prompted for the number.

  • Can you please solve it in script? I'm kind of confused of grep as I never work with it.Thanks – Nazmus Shakib Apr 27 '18 at 15:41
  • Just type it into a bash prompt, it won't break anything. – nohillside Apr 27 '18 at 15:44
  • It works but it also print some other lines containing 20.I can differ those with my desired line is whitespace.There is some whitespace before the book number and I only want to print the line when it matches with the book number not some other line.How can I do that.You can take a look on my input file.I give link in above.Thanks sir. – Nazmus Shakib Apr 27 '18 at 16:00
  • I add 2 more space in the grep and it works fine now.Thanks – Nazmus Shakib Apr 27 '18 at 16:04
  • btw What the *$ sign means.If I want to search for a string what should I change in the grep line.Thanks – Nazmus Shakib Apr 27 '18 at 16:11

You can use grep for this:

grep 56896 file.txt

If you wanted to script it, it could be something like this:



grep "$1" "$inputfile"

Which you would then run like:

$ ./script.sh 56896
  • I want to take input from user and then search the file with the input and if there is any match then print the whole line.My input file contains a lot of strings and integers. – Nazmus Shakib Apr 27 '18 at 15:39
  • @NazmusShakib: That is what the script would do – Jesse_b Apr 27 '18 at 15:44

To avoid catching book # 196 along with book # 96, I suggest a similar but more terse usage of grep:

grep ' 96$' file.txt

The $ symbol in regular expressions meaning 'the end of the text sample', so it will only match on the correct line.

This can also be put into a script:


grep " ${1}\$" /path/to/file.txt

This can also be done a bit more safely with awk:

awk -v book=96 '$NF == book {print}' file.txt

To print the lines for which the last word is something, awk comes to mind:

awk '$NF == "123"' # string comparison
awk '$NF == 123'   # number comparison, would also match on 0123, 123.0, 1.23e2
awk '$NF == ENVIRON["ENVVAR"]' # number comparison if both $NF and $ENVVAR
                               # look like numbers, string otherwise

For awk, those words by default are blank-separated. Depending on the implementation blank may be only space or tab characters, some may include other Unicode blank characters if classified as such in the locale. The busybox awk implementation also includes vertical spacing characters including the carriage return character.

If your file is formatted with MS-DOS line delimiters, that is the CR LF sequence of characters as opposed to just LF, then except with busybox awk, the above won't work. And even with busybox awk, the output lines would still have those problematic control characters that shouldn't be there on Unix.

So you should preprocess the input with dos2unix or d2u to convert the line endings to Unix format.

< file.dos dos2unix | awk '$NF == 123'

Your input file looks like it's made of records that are separated by blank lines. If you want to print the full records for a book number, you could do:

export BOOKNUMBER=123
< file.dos dos2unix | awk -v RS= -F '\n' '
    field[split($1, field, " ")] == ENVIRON["BOOKNUMBER"]'

There, we set the record separator to the empty string to enter the paragraph mode (records separated by blank lines), and the field separator to newline (aka LF) so the first line of each record is in $1 (the first field). We split that first line with the special " " field separator which is the default word splitting into the field array. And then compare the last element of that array (split() returns the number of elements, so field[split()] is the last element) with the content of the $BOOKNUMBER environment variable.

  • awk '$NF == 123' is OK with GNU Awk 4.1.4 if the line end with crlf – ctac_ Apr 27 '18 at 16:32

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.