-1

Is there a general way to do unix command and loop it over a list of files. For example, let's imagine we wanted to move all the files (but not directories) in a directory to another directory, but get prompted y/n before each one. Obviously, this can be done with a script, but is there a single command way to do this not just for mv, but for any similar do-something-to-a-file action (rm, cat, wc, grep, etc)?

  • Tyler, did either answer solve your problem? If so, please click the checkmark next to it; if not, please clarify the question to explain. Thank you! – Jeff Schaller Dec 10 '17 at 15:28
  • @JeffSchaller I will start voting for your answer when you start voting for my question. – Tyler Durden Dec 10 '17 at 15:34
  • I haven't voted against it, if that's what you're asking. – Jeff Schaller Dec 10 '17 at 15:35
2

Yes,

find /path/to/source/dir -type f -maxdepth 1 -ok mv {} /path/to/target/dir \;

The find command here will find all regular files in /path/to/source/dir and prompt the user for an ok to perform the given operation, which in this case will move the file to /path/to/target/dir. If the user presses y (and enter), the operation will be performed.

The {} will be replaced by the name of each found file in turn and the command that is executed for each file ends at \;.

If you replace -ok with -exec, the user will not be prompted, and the operation will be carried out on all files.

-maxdepth 1 restricts the search for files to the topmost directory (/path/to/source/dir). Without it, find would recurse down into all subdirectories under the given path.

-type f restricts the search to regular files only (that is, not directories, socket, device files etc.)

| improve this answer | |
0

In general, I would use shell globbing to generate the list of files that you wanted to act on, then perform a read & test in order to decide whether to perform the operation.

For (your) example:

for f in *
do 
  [ -f "$f" ] || continue
  read -p "mv $f to /tmp? "
  if [ $REPLY = "y" ]
  then 
    echo "moving $f to /tmp"
    # mv -- "$f" /tmp
  else 
    echo "not doing anything with $f"
  fi
done

Depending on your shell settings, this may or may not pick up dot-files (e.g. .bashrc).

You could vary this to taste -- to not echo for the "no" response; to allow for "y" or "Y" or "yes" or "yabadabadoo".

| improve this answer | |

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.