1

I'm trying to write a script that will loop through all subfolders of a directory to search for a specific file and then copy a new file to those folders that contain that file.

This is what I have so far:

#!/bin/sh
dir=/Documents
find "$dir" -name Sample.doc -printf "%p\n" | sort -nr | while read -r i; do
  echo "$i"
  done

This works to list all the Sample.doc files and their folders within the Documents folder.

However, I cannot find a way to extract the path from those folders to copy the new file into them.

Any help would be appreciated.

1

I think you are almost there. You can replace %p with %h in the -printf expression :

%h : Leading directories of file's name (all but the last element). If the file name contains no slashes (since it is in the current directory) the %h specifier expands to ".".

so the command would be something like :

find "$dir" -name Sample.doc -printf "%h\n" | sort -nr | while read -r i; do cp SomeFile "$i"; done

by the way, why is the sort part needed ?

| improve this answer | |
0

The dirname command removes the filename from the full path

| improve this answer | |
0

Using %h instead %p has already been suggested in another answer, but I'd like to add some improvements to make your code more robust. If, for instance, a matching directory contains a newline character in its name, you will in the best-case end up missing directories and getting some error messages from cp. At worst, you might override files anywhere on your system.

So instead, try doing it like this:

find "$dir" -name Sample.doc -printf "%h\0" | xargs --null -L1 cp SomeFile

The ACSII zero is guaranteed to never show up in any filenames, so unlike \n it works as a reliable separator for passing the paths. --null tells xargs to use the \0 as a input delimiter. It will then execute the given command (cp Somefile) once per item passed through the pipe, while appending the respective item as additional argument.

| improve this answer | |
0

In bash:

shopt -s nullglob globstar
for i in "$dir"/**/Sample.doc
do
    cp 'new file' "$(dirname "$i")"/
done

In fish:

for i in $dir/**Sample.doc
    cp 'new file' (dirname $i)/
end
| 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.