2

I am currently working with Jupyter notebooks. With an IDE I used to be able to look for parts of my code that could be elsewhere, and thus refactor as needed.

Suppose I have the following code:

 class.function('--parameter','-p', type = lambda x: operation(x,"%Y-%m-%d").date(),
                    default=unicode(previousTime-actualTime),
                    help='Send help'
                    )

The code is edited and is not meant to work or anything, I just want to exemplify the possibilty of there being multiple lines, multiple "strange" characters, quotes, and so on.

I now want to look where in my codebase that exact string exists.

I have been looking around and reading the manual and I have something like

 grep -rxno . -e "string starts
more text here %% 'parameters inside quotes'
string ends"

But I feel like since it is a regular expression is matching me with substrings that are similar, not necessarily the same. Also, and more confusing, it's giving results line per line:

./DMP3K/DMP_3K.py:30:class.function(
./DMP3K/DMP_3K.py:31:    
./DICC/diccionario.py:34:                        operation(x,"%Y-%m-%d").date()

I feel like there should be an easier way to do this operation that I am missing.

  • What operating system are you using? – terdon Jan 2 at 12:48
  • Ubuntu right now, but I connect through a VPN to a "server" machine so it would be *nix anyway. I should have clarified, though. – monkey intern Jan 2 at 15:53
  • 1
    Yes, please always mention the OS name. The distribution is less important, but we need to know if it's Linux or Unix or BSD or macOS or whatever since the versions of the basic tools are different. For instance, my answer requires GNU tools which are default on Linux but not on the others. – terdon Jan 2 at 16:13
2

If you have access to GNU grep (the default on Linux), you can use -z for this:

   -z, --null-data
          Treat  input  and output data as sequences of lines, each terminated by a
          zero byte (the ASCII NUL character) instead of a newline.  Like the -Z or
          --null  option,  this  option  can  be used with commands like sort -z to
          process arbitrary file names.

This will let you specify patterns that span multiple lines. Then, use -F so that the pattern isn't interpreted as a regular expression:

   -F, --fixed-strings
          Interpret PATTERN  as  a  list  of  fixed  strings  (instead  of  regular
          expressions), separated by newlines, any of which is to be matched.

Finally, save the search string in a variable:

$ IFS='' read -r -d '' pat <<EoF
> class.function('--parameter','-p', type = lambda x: operation(x,"%Y-%m-%d").date(),
>                     default=unicode(previousTime-actualTime),
>                     help='Send help'
>                     )
> EoF

To run the above, first write this into your terminal:

IFS='' read -r -d '' pat <<EoF

Then, paste the lines you are looking for and then write EoF. If the search string doesn't end in a new line, press Enter before writing EoF since that needs to be on its own line.

Now you can grep your files:

grep -z "$pat" /path.to/files/*

The above means

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.