0

I have several directories which contain hidden empty files. I need the name of these file names themselves, so I need to write the filenames to a txt file. My script looks like this:

cd /z/all_vendors/
x=`find vendors -perm 755`
for FILE  in $x; do
    ls -a $FILE >> locator.txt
done

However I get a permission denied error How do I write these hidden file names to a directory?

EDITS the vendors directory has subdirectories in the following way

vendors/
  |__000123
  |__000204
  |__000404

so x=`find vendors -perm 755` finds all subdirectories with certain permissions

Each of the 000xxx subdirectories have the following tree structure:

000xxx/
  .
  ..
  .kpypjn32rz6l
  .66jwvo6x96sj

etc where the hidden files start with a dot

I need to write the names of the hidden files to a txt file for example 'kpypjn32rz6l'

Fnechz
  • 1
  • 1
  • (1) [Bash pitfall number 1](https://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29). (2) [Quote](https://unix.stackexchange.com/a/131767/108618). (3) "Hidden" meaning "with names starting with a dot"? I'm asking because your code does not try to isolate such files (maybe because there are no non-hidden files?). (4) What does "the name of these file names themselves" mean? "Name of names"… what? – Kamil Maciorowski Nov 05 '21 at 22:51
  • hidden meaning they start with a dot, the name of the files represent location codes – Fnechz Nov 05 '21 at 22:53
  • 1
    `cd /z/all_vendors/ && find vendors -name '.*' >> locator.txt`? This is not an answer because although I think the command kinda matches the (not entirely clear) description, I'm not sure if this is what you want, because your code may run `ls -a` for directories and non-directories. Is `-perm 755` your way to find directories maybe? Sorry, there is so much weirdness in the code, I am confused about your desired output. Maybe if you posted an example directory tree (from the command `tree`, [edit] the question) and the desired output, we could fix your code so it generates the output you want. – Kamil Maciorowski Nov 05 '21 at 23:03
  • Also: what does "copy these hidden file names to a directory" mean? One can copy files (not names) to a directory. Your code writes some names to a file that is (hopefully) not a directory. IMO "copy names to directory" makes no sense. – Kamil Maciorowski Nov 05 '21 at 23:04
  • I have edited the question – Fnechz Nov 05 '21 at 23:23
  • OK, now we're getting somewhere. (5) How important is `-perm 755`? Do you want to skip directories with other permissions? Or is this your (peculiar) way to pick all directories to iterate over them later? (6) The name of `.kpypjn32rz6l` is `.kpypjn32rz6l` but you specified `kpypjn32rz6l`. Please confirm you want to remove the dot from the output. // I'm asking because `cd /z/all_vendors/ && find vendors -type f -name '.*' -exec basename -a -- {} + >> locator.txt` is quite straightforward and I have my doubts regarding if you really need to complicate it. Is `basename -a` available in your OS? – Kamil Maciorowski Nov 05 '21 at 23:41
  • Yes I need to skip other directories, I need to remove the dot from the output, and yes ```basename -a``` is available – Fnechz Nov 05 '21 at 23:45

1 Answers1

0
cd /z/all_vendors/ \
&& find vendors \
   \( -type d ! -path vendors ! -perm 755 -prune \) -o \
   \( -type f -name '.*' -exec basename -a -- {} + \) \
| sed 's/^\.//' >> locator.txt

Notes:

  • If cd fails then find will not be executed. This is good practice.
  • Any directory that doesn't match -perm 755 will be pruned (i.e. find will not descend into it), regardless of its depth. It could be wrong e.g. if you wanted to descend many levels regardless of permissions and only check permissions of the bottom-level directory. I understand your directory structure is quite flat, so this shouldn't be a problem. With ! -path vendors I ensure vendors will not be pruned, regardless of its permissions. (Note this is very sensitive to the path you supply to find as the starting point. find vendors/ … requires ! -path vendors/; find ./vendors … requires ! -path ./vendors etc.)
  • I assumed by "file" you mean "regular file", therefore -type f. Formally "file" is a broad term.
  • basename is a portable tool but its -a option is not portable. If your basename does not support -a then replace -exec basename -a -- {} + with -exec basename -- {} \;.
  • Hopefully the filenames to be printed don't contain any newline characters. Newlines will terminate names. The standard approach in case filenames may contain newlines is terminating with null characters. Terminating with null characters would complicate our solution and make locator.txt not a text file (POSIX definition of text file explicitly states it does not contain null characters).
  • sed removes one leading dot per line.
  • Files with identical names from different directories, if they match, will result in identical lines of output. Pipe to sort -u if you want to remove duplicate lines.
Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202