0

I have many .txt files in my directory which contain the lines starting with '='

For ex: a.txt has the following line( with spaces initially)

        =putSomething here;

How do I write a grep query which will match the above line? I tried the following,

find . -name "*.txt" | xargs grep -rn "^[=].*$"

4 Answers 4

2

Let's take this sample file:

$ cat file.txt
        =putSomething here;

Now, to find all such .txt files in the current directory:

$ grep -n '^[[:space:]]*=' *.txt
file.txt:1:        =putSomething here;

If you want to find all such .txt files in the current directory and all of its subdirectories, then use:

$ grep -rn '^[[:space:]]*=' --include '*.txt'
subdir/another.txt:1:        =putSomething here;
file.txt:1:        =putSomething here;

Notes

  1. find and xargs are not needed here. With the -r option, grep does recursive searching through subdirectories.

  2. --include '*.txt' limits grep to files matching the glob *.txt.

  3. ^ matches at the beginning of a line. [[:space:]]* matches zero or more whitespace characters. = matches an equal sign. In POSIX regular expressions, there is nothing special about = so it can be treated as any other character.

  4. Ending a grep regex with .*$ does not change which lines are matched. .*$ matches either if any characters or if no characters follow. The only reason to use .*$ is to change what grep highlights as matched text.

1
  • Find and glob are not equivalent because of the difference on how they treat dot-files, how and when they follow symlinks, and globing is affected by some options like GLOBIGNORE.
    – user232326
    Aug 22, 2017 at 2:38
2

A line that begins with = translates to the regex ^=.

Your find command should then be:

find . -name "*.txt" | xargs grep '^='

Or, better (avoid useless use of xargs):

find . -type f -name "*.txt" -exec grep '^[[:space:]]*=' {} +

(here, due to the ending +, only one grep is executed for a bunch of files)

3
  • 2
    user1449951 wrote with spaces initially.
    – Cyrus
    Aug 22, 2017 at 0:52
  • There are spaces initially and hence the above option didn't work. I tried grep -irn '^ *=' **/*txt Aug 22, 2017 at 2:02
  • @Arrow Thank you for fixing my last command, answer updated. Note that I never escape nor quote the ending + on Linux. If this is a problem on other systems, feel free to fix my answer.
    – xhienne
    Aug 22, 2017 at 9:36
0

Tried the below command and it seems to work.

grep -rn '^ *=' **/*txt
0

As an alternative to recursive grep and xargs:

$ find /dir -type f -name "*.txt" -exec grep -q '^[[:space:]]*=' {} ';' -print

This will look in /dir (and below) for all regular files whose names matches the given pattern. For each such file, if grep -q '^[[:space:]]*=' exits with a zero exit status (the pattern was matched somewhere in the file), then its name is outputted.

Or, if you just want to see the lines themselves:

$ find /dir -type f -name "*.txt" -exec grep '^[[:space:]]*=' {} '+'

The + at the end will feed as many filenames as possible to each invocation to grep whereas using ; as in my first example would feed only one file at a time.

You must log in to answer this question.

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