0

I have this command which works great

find . -type f -name *.txt -exec grep -li blah {} \;

Let's say the output will be:

/tmp/folder1/file1.txt
/tmp/folder2/myfile.txt
/tmp/thisfile.txt

If I was to do this:

find . -type f -name *.txt -exec grep -li -E --color blah {} \;

this would highlight the entire string. So /tmp/folder1/file1.txt would be highlighted.

Can I get it to highlight only the filename? So file1.txt, myfile.txt, thisfile.txt will be highlighted and nothing else.

Is this even possible?

DavidPostill
  • 162,382

2 Answers2

3
$ find --version
find (GNU findutils) 4.7.0

So, find does not do \x1b or \e, then let us help...

$ find -type f -maxdepth 2 -printf "%h/§[1m%f§[m\n" | sed -re 's/§/\x1b/g' 

In man find you will find(!) more of those %<character> thingies.
They define what you want to have printed.

Here %h prints the first portion of the path, and %f the last portion of it (which usually is the filename) ...

NOTED:

$ find -type f -maxdepth 2 -printf "%h/$(tput bold)%f$(tput sgr0)\n"

... this is "nicer" as it will be terminal-type agnostic (as long as tput, ncurses-bin is installed); as is:

$ find -type f -maxdepth 2 \  
-printf "%h/$(setterm --reverse on)%f$(setterm --reverse off)\n"

Ref: man termifo for "bold" and similar, or even man setterm (from util-linux) as a replacement for tput

Hannu
  • 10,568
0

This is a general-purpose filter that highlights text from the last / in a line to the end of the line. If there is no / then the whole line will be highlighted. Trailing / characters are treated like non-/.

highlight() (
if [ -t 1 ] || [ "$1" = -f ]; then
   start="$(tput bold)"
   end="$(tput sgr0)"
   sed "s|[^/]*./*$|$start\\0$end|;t;s|.*|$start\\0$end|;"
else
   cat
fi
)

Examples:

  1. highlight <<EOF
    dir/dir/file
    dir/dir/
    dir/dir/////
    no-slash
    /
    .
    EOF
    
  2. find . | highlight
    
  3. grep -lr . | highlight
    

Notes:

  • The filter can take input from find, grep or anything. The filter does not rely on non-portable find -printf.

  • tput bold and such are not portable though. Adjust start= and end= to your needs.

  • Inside the sed code | is used as a delimiter for s. It's crucial not to have | from the expansion of $start or $end. Adjust to your needs. Remember s in sed can use almost any character as delimiter.

  • The filter tests if its stdout is a terminal. If not, it becomes cat (i.e. a no-op filter). You can force highlighting even to a non-terminal with highlight -f. Example:

    find . | highlight -f | head -n 3