0

I am now developing a script to copy some files from directory A to multiple directories B following some directives , the script is working fine , but when it comes to files with spaces on them , he just considers them as multiple files , for example:

my_super_cool_file_2007039904_11 (3rd copy).pdf

when the file is in this loop:

for i in $(find $parent -mindepth 1 -maxdepth 1 -type f|cut -c 11-);do
echo "this is the file: $i" 
done

it is considered as multiple files :

  this is the file: my_super_cool_file_2007039904_11
  this is the file: (3rd 
  this is the file: copy).pdf

i've tried replacing the space with \space using sed 's/ /\\ /g' but it does not seem to solve my problem, for the loop it's 3 different files, i had also the same problem using ls, and i need to stick to use find

Kingofkech
  • 1,028

3 Answers3

1

Assuming the cut -c 11- is intended to remove the directory part of the file path, with GNU find:

find "$parent" -mindepth 1 -maxdepth 1 -type f -printf \
  'this is the file: %f\n'

With any POSIX find:

find "$parent/." ! -name . -prune -type f -exec sh -c '
  for file do
    file=${file##*/}
    printf "this is the file: %s\n" "$file"
  done' sh {} +

More reading at:

  • Thank you for your answer ,and to give you a better idea about the problem , ./A/B/C/myfile.pdf i need to get the name of thedirectory C and then depending on it's name i'll move the fiel to another location , so i only need to correct the space problem , and what does the -prune do ?. – Kingofkech Oct 04 '17 at 09:14
  • @Kingofkech -prune tells find not to descend into that directory. That's the standard approach at implementing GNU find's -maxdepth. – Stéphane Chazelas Oct 04 '17 at 09:18
  • That C would be "$(basename -- "$parent"}" or "${parent##*/}" since you're getting files at depth 1, so it should be a matter of case $parent in (*/C) find "$parent" -mindepth 1 -maxdepth 1 -type f -exec mv {} /some/where \;; esac, that doesn't explain why you'd want to strip the first 10 bytes of each line of each file path. – Stéphane Chazelas Oct 04 '17 at 09:22
1

Since you're using -maxdepth 1 and -mindepth 1, you may as well just do a simple loop (in bash):

for name in "$parent"/*; do
    if [ -f "$name" ]; then
        dir=${name%/*}  # dir=$( dirname "$name" )
        dir=${dir##*/}  # dir=$( basename "$dir" )
        printf 'The directory is "%s"\n' "$dir"
    fi
done

Looping over the result of find is generally bad practice: Why is looping over find's output bad practice?

Kusalananda
  • 333,661
  • Thank you for your answer ,and to give you a better idea about the problem , ./A/B/C/myfile.pdf i need to get the name of thedirectory C and then depending on it's name i'll move the fiel to another location , so i only need to correct the space problem. – Kingofkech Oct 04 '17 at 09:14
  • @Kingofkech The changes I just made will pick out the name of the directory. – Kusalananda Oct 04 '17 at 09:20
  • Note that (contrary to find) it would not include hidden files and [ -f "$name" ] would be the equivalent of GNU find's -xtype f (also include symlinks provided they point to regular files). – Stéphane Chazelas Oct 04 '17 at 09:27
-1

Put the $(find $parent -mindepth 1 -maxdepth 1 -type f|cut -c 11-) in quotes and so:

 "$(find $parent -mindepth 1 -maxdepth 1 -type f|cut -c 11-)"
  • It did not work , any other suggestion ? – Kingofkech Oct 04 '17 at 08:52
  • @Kingofkech "Did not work"? In what specific way did it not work? – Kusalananda Oct 04 '17 at 09:03
  • it did not work because it only loops one time, it returns the full loop into the variable in one sigle time , let me explain: for i in "$(find $parent -mindepth 1 -maxdepth 1 -type f|cut -c 11-)";do the variable i will contain al the output : file1 file2 file3 concatenated. – Kingofkech Oct 05 '17 at 10:40