1

I am trying the list all the subfolders within a folder:

find . -type d -maxdepth 1 -mindepth 1 2>/dev/null | while read dir
do 
  echo $dir

done

However, what I get printed out is

./dir1
./dir2

while I would need only

dir1
dir2

Complete use case:
later, I would like to create a new file with name of the folder e.g:

find . -type d -maxdepth 1 -mindepth 1 2>/dev/null | while read dir
do 
  echo 'MOVING TO'$dir
  cd $dir
  #SUMMARYLOG=$dir_log_merged # HERE IS WHERE THE ./ IS PROBLEMATIC
  # QUESTION EDITED
  SUMMARYLOG=${dir}_log_merged # HERE IS WHERE THE ./ IS PROBLEMATIC

  echo -e "\n""\n"'SUMMARY LOGS TO '$SUMMARYLOG
  touch $SUMMARYLOG
  pwd

  find . -size +0c -type f -name '*.err'  | xargs -I % sh -c  'echo % >> {$SUMMARYLOG}; cat % >> "{$SUMMARYLOG}"; echo -e "\n" >> "{$SUMMARYLOG}"'

  cat $SUMMARYLOG
  cd ..
done

Basically, I would like to merge a set of .err files in each of the subfolders and create one file with the subfolder name. I can not create my $SUMMARYLOG so I think the problem is in the find output ./dir...

00__00__00
  • 4,834
  • 9
  • 41
  • 89

1 Answers1

3

Instead of find acrobatics, you could use a glob and parameter expansion:

for d in */; do echo "${d%/}"; done

where the "${d%/}" removes the trailing slash from each directory name.

If you have hidden directories, you have to add a second glob as */ ignores them:

for d in */ .[!.]*/; do echo "${d%/}"; done

where .[!.]*/ is a glob for "begins with . and is followed by anything but another .", to exclude . and ...

Apart from that, if you have $dir, you can't use $dir_log_merged to append _log_merged to it, as Bash will look for a variable called dir_log_merged. You have to use ${dir}_log_merged instead.

Another set of problems is in your xargs command that starts with

sh -c  'echo % >> {$SUMMARYLOG};
  • Single quotes prevent variables from expanding
  • SUMMARYLOG would be invisible in the subshell; you'd have to export it first
  • {$SUMMARYLOG} expands to the contents of $SUMMARYLOG (empty string, in your case), then surrounds that with {}, which is why you see the {} file being created
  • You can't use % like this within the sh -c command. You have to use it as an argument to sh -c and then refer to it like this:

    sh -c 'echo "$1"' _ %
    

    with _ as a dummy argument that becomes $0 within the sh -c command.

And finally, I would solve your task as follows:

for f in */*.err; do
    ! [[ -s $f ]] && continue           # Skip empty files
    {
        echo "${f##*/}"                 # Basename of file
        cat "$f"                        # File contents
        echo                            # Empty line
    } >> "${f%/*}/${f%/*}_log_merged"   # Dirname plus new filename
done
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
  • thanks. We are getting close. I think I have messed up also with the file names given to the xargs command. I am now able to create files with right content, but they are named {} instead of my desired name. what is still wrong? – 00__00__00 Oct 25 '17 at 14:13
  • @Liborio Are the `.err` files directly in the subdirectories, or nested in sub-subdirectories? – Benjamin W. Oct 25 '17 at 14:16
  • directly in the subdirectories – 00__00__00 Oct 25 '17 at 14:17