2

I want to search my code base for ocurrences of a string, and then get the formatted output as filename, line number, and code lide. I got it as I wanted on the first line of the output, but the coming lines loses the wanted formatting.

$ find src/ -name "*.js" | xargs grep --null -E -n 'filter\(|map\(' | xargs -0 printf "%-100s%-5s%-100s" > test.txt

The output is as follows: (scroll right to see the complete line)

src/components/AppRouterSwitch.js                                                                   15:    return _Routes.map((route, index) => {
src/components/forms/UserEditForm/UserEditForm.js36:    const options = UserTypes.map((type, index) => <option key={index} value={type.type}>{type.name}</option>);
src/components/pages/AdminPage/SolutionManagementEditPage/SolutionManagementEditPage.js119:        templates:state.templates.filter(item=>item.SOLUTIONID ==id)
src/components/pages/AdminPage/SolutionManagementEditPage/SolutionManagementEditPage.js120:            .map(item=>{return{

The first row looks just as I want it. The following loses the desired formatting. Ending the printf format string with /n doesn't do the trick.

3
  • 1
    Try to use the standard option of grep -l (a lowercase L)
    – malyy
    Commented Nov 13, 2018 at 9:59
  • 1
    @malyy I tried that with some variations but no success. I don't see how the -l option would help me. -l, --files-with-matches Suppress normal output; instead print the name of each input file from which output would normally have been printed. The scanning will stop on the first match.
    – Max
    Commented Nov 13, 2018 at 10:08
  • please check my answer and clarify if you really want the colon (:) after the line number
    – user313992
    Commented Nov 13, 2018 at 14:03

2 Answers 2

2
find src/ -type f -name '*.js' -exec grep -Hn -E -- 'filter\(|map\(' {} + |
    awk -F: '{printf "%-100s%-5s%-100s\n", $1, $2, substr($0, length($1) + length($2) + 3)}'

The -H option to grep will cause it to print the filename even when called with a single file as argument. The -type f option to find is needed in order to skip broken links and directories that happen to be named *.js.

Or even simpler, get rid of grep completely (thanks to @don_crissti for the suggestion):

find src/ -type f -name '*.js' -exec awk '/filter\(|map\(/{printf "%-100s%-5s%-100s\n", FILENAME, FNR, $0}' {} +
1
  • Elegant solution, just what I needed. The colon is not necessary.
    – Max
    Commented Nov 13, 2018 at 19:22
0

man makes it a bit unclear. "The scanning will stop on the first match" - indicates that all file names will be printed, but the scanning for the matching word will stop at the first occurence. GNU grep man page clarifies this:

-l
--files-with-matches
Suppress normal output; instead print the name of each input file from which output would normally have been printed. The scanning of each file stops on the first match. (-l is specified by POSIX.)

Here is an example:

$grep -iR Intel * 
2018/jan/cpu.txt:Intel i9 
2018/motherboard.txt:Intel Motherboard 
hardware.txt:Intel Corei7
#the same result as you provided;

$grep -iRl Intel * 
2018/jan/cpu.txt
2018/motherboard.txt
hardware.txt
#the desired result
1
  • Not quite what I wanted. Please scroll the output to the right and you'll se that I also want line number and line of code, but formatted as on the first row.
    – Max
    Commented Nov 13, 2018 at 12:08

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.