I'm looking to write a bash script that recursively searches directories, find a particular string, then opens to that string in that particular file.

I call this function exert because it takes away the exertion of finding a particular variable in my software. For e.g. if my website uses a phrase like "I like big cats" in a div, and I want to edit just that div, I can type "exert 'I like big cats'" and it will open the file holding that div along with the exact spot that div is at.

Here is my code so far:

echo "Searching for $1"
echo "----Inside files----"
grep --color=always  -nr "$1" * > /tmp/tmpsearch; #searches for ' I like big cats'
filesNew=`cat /tmp/tmpsearch` #stores it in a variable that can be split - future version will keep this in memory 
readarray -t files <<<"$filesNew" #it is split to an array called $files
IFS=":"; #":" is the string delimter for grep's output of files with the string, alongside the line number the string is found inside the file 
for i in "${files[@]}"; do
    #The colon operator separates grep's output of line numbers and files that contain the string 'I like big cats'
    read -ra FOUND <<< "$i" 
    printf "Found index: $x\n"
    line=`echo "${FOUND[1]}"`
    file=`echo "${FOUND[0]}"`

    nano +$line ./$file #This should open nano at the exact line number 

exit 1

Everything works fine, but nano seems to be interpreting an encoding error when being called with an array output from a bash script.

Although the strings are fine inside the bashscript, nano will read a file name like ./app.vue as ./^[[35m^[[Kapp.vue^[[m^[[K^[[36m^[[K. There a lot of command characters around the file name that I can't seem to get rid of.

By placing nano app.vue at the start of the script, which works, I know this isn't a problem with just nano or just bash, but a problem with them working with an array output (the string split from grep)


Those are colourising strings: ^[ is ESC, [..m is foreground colour etc for your terminal.

Set grep --color=never


The problem arises from using grep --color=always as the first command.

Apparently, bash keeps track of color for its shell using the control characters I listed above.

So, ./^[[35m^[[Kapp.vue^[[m^[[K^[[36m^[[K is actually telling bash, "this string has text app.vue, with purple text coloring". Nano, however, is colorblind.

If you want, you can try and escape these color indicators from the string using normal regex procedures.

In my case, I was lucky enough to just tell grep --color=never instead of --color=always. The problem went away with that.

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.