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 "^[=].*$"
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.

  • 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. – Arrow Aug 22 '17 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)

  • 2
    user1449951 wrote with spaces initially. – Cyrus Aug 22 '17 at 0:52
  • There are spaces initially and hence the above option didn't work. I tried grep -irn '^ *=' **/*txt – user1449951 Aug 22 '17 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 '17 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.

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.