17

I have a case where multiple .bz2 files are situated in subdirectories. And I want to search for a text, from all files, using bzcat and grep command linux commands.

I am able to search one-one file by using the following command:

bzcat <filename.bz2> | grep -ia 'text string' | less

But I now I need to do the above for all files in subdirectories.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Semu
  • 223
  • 1
  • 2
  • 8

4 Answers4

31

You can use bzgrep instead of bzcat and grep. This is faster.

To grep recursively in a directory tree use find:

find -type f -name '*.bz2' -execdir bzgrep "pattern" {} \;

find is searching recursively for all files with the *.bz2 extension and applies the command specified with -execdir to them.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • Good one! Didn't know about bzgrep, so I am deleting my approach. – fedorqui Jan 07 '14 at 11:42
  • 1
    I just knowed about `zgrep`, so I tried `man bzgrep`. thx! :) – hek2mgl Jan 07 '14 at 11:44
  • Thanks hek2mgl, I am running the command and will let you know of the result. The files I am searching from are too big. – Semu Jan 07 '14 at 12:28
  • Just to confirm something. Do I put my search text string in "pattern", replacing pattern with my string? – Semu Jan 07 '14 at 12:40
  • @user3041655 yes. replace pattern with your actual grep pattern – hek2mgl Jan 07 '14 at 13:10
  • Thanks. So if I want to less(view) the result, how do I modify the command? Because bzgrep is not installed in my server, I had to replace it with bzcat. When running the modified command, it ran until the end by never showed any matching string. And I know the string is in the file. – Semu Jan 07 '14 at 13:19
  • This is the comand: `find -type -file -name 'SystemOut.log.bz2' execdir bzcat "62123456" {} \;` – Semu Jan 07 '14 at 14:09
  • It should be: `find -type f -name 'SystemOut.log.bz2' -execdir bzcat "62123456" {} \;` – hek2mgl Jan 07 '14 at 14:58
  • Thanks hek2mgl. With your assistance, I finally got it working with the following command: `find . -type f -name 'SystemOut.log.bz2' -exec bzcat {} \; | grep -ia '3861449' | less` – Semu Jan 08 '14 at 07:09
  • Works. Is it possible to output the file name and maybe line as well? – robsch Jun 04 '19 at 08:48
5

There are several methods:

bzgrep regexp $(find -name \*.bz2)

This method will work if number of the found files is not very big (and they have no special characters in the pathes). Otherwise you better use this one:

find -name \*.bz2 -exec bzgrep regexp {} /dev/null \;

Please note /dev/null in the second method. You use it to make bzgrep print the filename, where the regexp was found.

Igor Chubin
  • 61,765
  • 13
  • 122
  • 144
5

Just try to use:

bzgrep --help
grep through bzip2 files

Usage: bzgrep [grep_options] pattern [files]

For example, I need grep information from list of files by number 1941974:

'billing_log_1.bz'
'billing_log_2.bz'
'billing_log_3.bz'
'billing_log_4.bz'
'billing_log_5.bz'

What can I do?

bzgrep '1941974' billing_log_1

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Anton Shtin
  • 61
  • 1
  • 3
0

Continuous your code with fixes by bzcat:

find . -type f -name "*.bz2" |while read file
do 
    bzcat $file | grep -ia 'text string' | less
done
BMW
  • 42,880
  • 12
  • 99
  • 116
  • Yes, you need save it in a bash file, such as a.sh, then give the execute permission by : chmod +x a.sh – BMW Jan 07 '14 at 20:16