3
\$\begingroup\$

For the input section of a script, I wrote a snippet using a while loop and an if statement to check whether there are matches for the $search. Only if there are matches does it move on to the input of $replace; if there are no matches it asks for $search again.

 while true; do
     echo "Please enter token to be replaced: "
     read -e -r search
     match="$(find . -maxdepth 1 -path "*${search}*" -printf "." | wc -c)"
     if [ "${match}" -gt 0 ]; then
         echo "${match} file(s) found"
         break
     else
         echo "no matches found!"
         echo
     fi
 done

 echo "Please enter replacement: "
 read -e -r replace

# I used the following command to check if the output was right
# echo "rename 's/$search/$replace/g' ./*"

In this snippet I used advice I got from a question I asked on Stack Overflow.

This code is going to be used as the input section of a rename script. In the last line I added an echo "rename... command to check if the output works as expected.

The script is meant to process all files matching the $search criteria in the current directory. Therefore I used find . -maxdepth 1....

The script of which this snippet is part of got reviewed here earlier.

Does this code match general standards?

\$\endgroup\$
  • 1
    \$\begingroup\$ -path uses a shell pattern, while s/// uses a regular expression. Therefore, if you search for a.c, file abc won't be found by find, even though rename would match and rename it. Similarly, a?c would find abc, but replace won't match it. \$\endgroup\$ – choroba Aug 2 '17 at 12:49
  • \$\begingroup\$ Are you defining a function or a script? There's no sign that this code is turned into a shell function. Did you leave out code? \$\endgroup\$ – chicks Aug 2 '17 at 13:14
  • \$\begingroup\$ sorry, I'm pretty new to programming, function was not the right term I guess. I'm writing a script. I change this in the question... \$\endgroup\$ – nath Aug 2 '17 at 13:17
  • \$\begingroup\$ @choroba I tried to go this way: find . -maxdepth 1 -regextype sed -regex "*${search}*" -printf "." | wc -c but I did not get it to work. Also I wasn't sure witch regextype to choose, I thought sed was the closest to rename, but please correct me... \$\endgroup\$ – nath Aug 3 '17 at 0:12
  • \$\begingroup\$ rename uses perl regexes which might be unsupported by find. \$\endgroup\$ – choroba Aug 3 '17 at 5:34
2
\$\begingroup\$

If you want to match by the same pattern as rename, then it's probably best to use perl. To be really pedantic and support filenames with embedded newlines, you could use -print0 of find, and then in perl split the output by \0 characters and filter with the grep function:

find . -maxdepth 1 -print0 | perl -ne "print scalar grep /$search/, split /\0/"

Putting in your script:

 while true; do
     echo "Please enter token to be replaced: "
     read -e -r search
     match=$(find . -maxdepth 1 -print0 | perl -ne "print scalar grep /$search/, split /\0/")
     if [ "${match}" -gt 0 ]; then
         echo "${match} file(s) found"
         break
     else
         echo "no matches found!"
         echo
     fi
 done
\$\endgroup\$
  • \$\begingroup\$ Thank you janos, this works perfect! Looks like after all I kind of have to (at least a little) get into perl :-) AWESOME! \$\endgroup\$ – nath Aug 3 '17 at 22:00

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.