0

I am gathering a list of directories that I need to search for a file using ls /opt/logs/ | grep '10\.22\.[0-9]*[02468]\.\d*' and that is working.

But when I try to prepend /opt/logs/ to the result of that command, with printf, I get only the first value of the array prepended.

I have tried explicitly iterating through the array in a C-style for loop and I have tried multiple different format strings for printf.

      if [[ 1 == $ROBOTS_ONLY ]]; then
        LOGS=/opt/logs/10\.22\.^\d*[02468]$\.*/$LOGFILE-$FILEDATE
        FINDSTR='10\.22\.[0-9]*[02468]\.\d*'
      elif [[ 1 == $LOCKERS_ONLY ]]; then
        LOGS=/opt/logs/10\.22\.^\d*[13579]$\.*/$LOGFILE-$FILEDATE
        FINDSTR='10\.22\.[0-9]*[13579]\.\d*'
      elif [[ 1 == $BOTH ]]; then
        LOGS=/opt/logs/10.22.*/$LOGFILE-$FILEDATE
        FINDSTR='10\.22\.*'
      fi

      LOGCOUNT=$(ls /opt/logs/ | grep $FINDSTR | wc -l)
      LOGFILES=$(ls /opt/logs/ | grep $FINDSTR)
      PREFIX='/opt/logs/'
      # for (( i=0 ; i <= LOGCOUNT ; i++ )); do
      #   LOGFILES[i]="$PREFIX${LOGFILES[$i]}"
      #   if [[ 1 == $DEBUG ]]; then echo "${LOGFILES[i]}"; fi
      # done
      LOGFILES=$(printf "/opt/logs/%s\n" "${LOGFILES[@]}" )
      if [[ 1 == $DEBUG ]]; then echo "LOGCOUNT: $LOGCOUNT"; printf '%s\n' "${LOGFILES[@]}"; fi

This is what I am getting:

/opt/logs/10.22.0.1
10.22.0.10
10.22.0.100
10.22.0.101
10.22.0.102
10.22.0.103
10.22.0.104
10.22.0.105
10.22.0.106
10.22.0.107
10.22.0.108
10.22.0.109
10.22.0.11
10.22.0.110
10.22.0.111
10.22.0.112
10.22.0.113
10.22.0.114
10.22.0.115
10.22.0.116

What I am expecting is:

/opt/logs/10.22.0.1
/opt/logs/10.22.0.10
/opt/logs/10.22.0.100
/opt/logs/10.22.0.101
/opt/logs/10.22.0.102
/opt/logs/10.22.0.103
/opt/logs/10.22.0.104
/opt/logs/10.22.0.105
/opt/logs/10.22.0.106
/opt/logs/10.22.0.107
/opt/logs/10.22.0.108
/opt/logs/10.22.0.109
/opt/logs/10.22.0.11
/opt/logs/10.22.0.110
/opt/logs/10.22.0.111
/opt/logs/10.22.0.112
/opt/logs/10.22.0.113
/opt/logs/10.22.0.114
/opt/logs/10.22.0.115
/opt/logs/10.22.0.116
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
cptully
  • 615
  • 1
  • 9
  • 24
  • `LOGFILES` has a single string, not an array with one item per. That's because `foo=$(bar)` reads `bar`'s output into a string, not an array. So instead of `printf` evaluating the format string once per array item, you only *have* one item (which happens to have a bunch of newlines in it), so it only runs once total. – Charles Duffy Sep 18 '19 at 12:18
  • BTW, right now, this code doesn't constitute a [mre] -- it's not *minimal* because it has contents unrelated to the problem, and it's not *reproducible* because nobody but you can run it (we don't have the expected filenames). – Charles Duffy Sep 18 '19 at 12:19
  • BTW, see also: [Why you don't parse the output of `ls`](http://mywiki.wooledge.org/ParsingLs). Much better to use NUL-delimited output instead of newline-delimeted output, as NULs (unlike newlines) can't possibly exist as literals in filenames -- `find ... -print0` will generate the former, and on a new enough version of bash, `readarray -d '' dest_array_name` will consume it. – Charles Duffy Sep 18 '19 at 12:20
  • See also [UsingFind](https://mywiki.wooledge.org/UsingFind) describing the generation/filtering end with `find`. Even if there weren't correctness issues, that would be more efficient anyhow, since you're not printing filenames you don't need (and `find` doesn't do slow/inefficient things `ls` does like sorting the filenames without being asked). – Charles Duffy Sep 18 '19 at 12:26
  • I am not surprised my question is a duplicate - there seem to be lots of questions online on this topic and I was getting overwhelmed with scanning through the answers. Thanks for the links. I will read them all. – cptully Sep 18 '19 at 12:39

0 Answers0