0

I need to save content of two directories in an array to compare them later. Thats the solution i write:

DirContent()    
{
        #past '$1' directorys to 'directorys'
        local DIRECTORYS=`ls -l --time-style="long-iso" $1 | egrep '^d' | awk '{print $8}'`
        local CONTENT
        local i
        for DIR in $DIRECTORYS
        do
                i=+1
                CONTENT[i]=${DIR}
        done
        echo $CONTENT
}

Then when I try to print this array I get empty output. Both directories are not empty. Please tell me what am I doing wrong here. Thanks, Siery.

  • 1
    are you sure about `i=+1`? I think it should be `((i=i+1))` – Hossein Nasr Jan 13 '16 at 03:52
  • Yes. You have right. 'i=+1' adds element to an array when '((1=i+1))' modify value. Probably next error i make was 'CONTENT[i]' not 'CONTENT[$i]'. But function still returns empty arrays, problem is somewhere else. –  Jan 13 '16 at 04:11
  • 1 = i+1 surely not, 1 can't be the LHS of an assignment. 1 is always 1. – user unknown Jan 13 '16 at 04:15
  • Sorry, i misspell, it's 5 am in Europe :). *'((i=i+1))' –  Jan 13 '16 at 04:19
  • You know that 'print $8' will fail if you have blanks in filenames and the like? Can you exclude such patterns? Btw: If your ability to post questions is that much affected by the time, you should go to sleep and ask when fit again. And why don't you use `content=($(ls -l ... '{print $8}')` to create the array? to produce the array? – user unknown Jan 13 '16 at 04:25
  • Yes, i was just thinking the same when i look at this code. That i can just write this function in two lines. Any ways, no, i don't know how to fix that problem you mention. I start learning bash 2 days ago. Can you help me with that? This is backup script so i cant know what files am i going to deal with. –  Jan 13 '16 at 04:59
  • Recommended reading: [BashGuide](http://mywiki.wooledge.org/BashGuide)! – Benjamin W. Jan 13 '16 at 05:42

2 Answers2

1

The core of this question is answered in the one I marked as a duplicate. Here are a few more pointers:

  • All uppercase variable names are discouraged as they are more likely to clash with environment variables.
  • You assign to DIRECTORYS (should probably be "directories") the output of a complicated command, which suffers from a few deficiencies:
    • Instead of backticks as in var=`command`, the syntax var=$(command) is preferred.
    • egrep is deprecated and grep -E is preferred.
    • The grep and awk commands could be combined to awk /^d/ '{ print $8 }'.
    • There are better ways to get directories, for example find, but the output of find shouldn't be parsed either.
    • You shouldn't process the output of ls programmatically: filenames can contain spaces, newlines, other special characters...
  • DIRECTORYS is now just one long string, and you rely on word splitting to iterate over it. Again, spaces in filenames will trip you up.
  • DIR isn't declared local.
  • To increase i, you'd use (( ++i )).
  • CONTENT[i]=${DIR} is actually okay: the i is automatically expanded here and doesn't have to be prepended by a $. Normally you'd want to quote your variables like "$dir", but in this case we happen to know that it won't be split any further as it already is the result of word splitting.
  • Array indices start at zero and you're skipping zero. You should increase the counter after the assignment.
  • Instead of using a counter, you can just append to an array with content+=("$dir").
  • To print the contents of an array, you'd use echo "${CONTENT[@]}".

But really, what you should do instead of all this: a call DirContent some_directory is equivalent to echo some_directory/*/, and if you want that in an array, you'd just use

arr=(some_directory/*/)

instead of the whole function – this even works for weird filenames. And is much, much shorter.

If you have hidden directories (names starts with .), you can use shopt -s dotglob to include them as well.

Community
  • 1
  • 1
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
0

You can try

        for((i=0;i<${#CONTENT[*]};i++))
        do
             echo ${CONTENT[$i]}
        done

instead of echo $CONTENT

Also these change are required

     ((i=+1))
     CONTENT[$i]=${DIR} 

in your above code

Varun
  • 447
  • 4
  • 9