5

I have an script that search for some files, some of them with whitespaces, and due to that I'm using while read. Inside of such loop I need to use read -p "Pause" for waiting for a key on each interaction. However rather than waiting for a key it is reading the first letter of the pipeline. I need something like this:

find . -name "*.o3g" | grep "pattern" | while read line
do
    process "$line"
    read -p "Press any key to continue"
done

1 Answers1

5

Since you're already using bash-specific code, either do (assuming GNU grep or compatible):

find . -name '*.o3g' -print0 | grep -z pattern |
  while IFS= read -rd '' file; do
    process "$file"
    read -n1 -p 'Press any key to continue' < /dev/tty
  done

(where the character (note however that some keys send more than one character) is read from the controlling terminal).

Or, better since that also avoids process's stdin from being the pipe from grep:

while IFS= read -u 3 -rd '' file; do
  process "$file"
  read -n1 -p 'Press any key to continue'
done 3< <(find . -name '*.o3g' -print0 | grep -z pattern)

(where the character is read from the unmodified stdin).

See also Why is looping over find's output bad practice? for other potential problems with the way you process find output.

Here, maybe you can simply do:

find . -name '*.o3g' -path '*pattern*' -ok process {} \;

See also, to avoid any GNUism except bash itself:

find . -name '*.o3g' -exec bash -c '
  for file do
    [[ $file =~ pattern ]] || continue
    process "$file"
    read -n1 -p "Press any key to continue"
  done' bash {} +