0

I have a stupid problem. I've been trying to create a bash script for checking if a .tif file exists based on a path found in an auto generated .txt file. The problem, however, is that I can't get my code to echo out all the contents of my TIF_PATH array, it only shows the first entry found.

Example of .txt file:

INPUT_FILE_DOC_TIF=/home/user/documents/tif.tif

Any idea what I'm doing wrong? As you can see, I'm a big noob.

Thanks in advance.

count_recursive () 
{ 
   command find "${1:-.}" -type f -name "${2:-*}" -print0 | 
       command tr -dc '\0' | command wc -c;
return 0
}



#FIND_TXT = Finds .txt files for the array. 
FIND_TXT=$(find . -type f -name "*.txt")

Used for creating the array, and finding the auto generated .txt files.

#Save and change Internal Field Seperator (used to remove potential blank spaces, breaks and seperators)
OLDIFS=$IFS

IFS=$'\n'

#Read all file names into an array
declare -a FILE_ARRAY=($FIND_TXT)

#Restore it 
IFS=$OLDIFS

#Get length of array
declare -a tLen=${#FILE_ARRAY[@]}

#Output path to a new variable, TIF_PATH, via egrep. 
declare -a TIF_PATH=$(egrep "INPUT_FILE_DOC_TIF" "${FILE_ARRAY[$@]}" | sed 's#INPUT_FILE_DOC_TIF=##g')
#Output path without file name. 
#declare -a PISS_PATH=$("${TIF_PATH}" | sed 's/..........$//')

#Use for loop to read all filenames
for (( i=0; i<${tLen}; i++ ));

    do
        echo    "$i"
        echo    "${FILE_ARRAY[$i]}"
        #Can be changed to output all, instead of increment. 
        echo    "${TIF_PATH[$i]}"
        #find . -type f -print | xargs grep ""
        #echo   "${PISS_PATH[$@]}"


        #find . -type f -name "$TIF_PATH")


done

And the result:

./txt/asd.txt
/home/user/Documents/Scripts/tiffile.tif
1
./txt/1000001.txt

2
./txt/111100001.txt

3
./txt/0047-001124-000000001.txt

4
./test/0047-001124-000000001.txt

5
./0047-001124-000000001.txt
3
  • Try tLen=${#FILE_ARRAY[@]} Commented Sep 3, 2014 at 8:13
  • unrelated,but: try avoid UPPERCASE_ONLY variable names. Can collide with Environment variables... Commented Sep 3, 2014 at 8:15
  • Okay, it's not an array any longer. Okay, I didn't know that about uppercase variables - I'll keep that in mind! Commented Sep 3, 2014 at 8:29

2 Answers 2

1

Demo of your problem and possible solutions

title() { printf "\n%-80.80s\n" "===[$*]$(printf "%80s" | tr ' ' '=')";}

title "demo output: lines what should go into array"
egrep 'root|daemon' /etc/passwd

title "your solution - puts all lines into arr[1] "
declare -a arr1=$(egrep 'root|daemon' /etc/passwd)
echo "array size: ${#arr1[@]}"
for ((i=0; i<${#arr1[@]}; i++))
do
    echo "$i: ${arr1[$i]}"
done

title  "alternative - creates 3 array elements - but keeps '\n'"
readarray arr2 < <(egrep 'root|daemon' /etc/passwd)
echo "array size: ${#arr2[@]}"
for ((i=0; i<${#arr2[@]}; i++))
do
    echo "$i: ${arr2[$i]}"
done

title "as list, breaks on IFS (default on spaces too) - more elements as lines"
arr3=($(egrep 'root|daemon' /etc/passwd))
echo "array size: ${#arr3[@]}"
for ((i=0; i<${#arr3[@]}; i++))
do
    echo "$i: ${arr3[$i]}"
done

title "as previous breaks on IFS, but only on '\n' "
IFS=$'\r\n' arr4=($(egrep 'root|daemon' /etc/passwd))
echo "array size: ${#arr4[@]}"
for ((i=0; i<${#arr4[@]}; i++))
do
    echo "$i: ${arr4[$i]}"
done
unset IFS

produces

===[demo output: lines what should go into array]===============================
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
_cvmsroot:*:212:212:CVMS Root:/var/empty:/usr/bin/false

===[your solution - puts all lines into arr[1] ]================================
array size: 1
0: root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
_cvmsroot:*:212:212:CVMS Root:/var/empty:/usr/bin/false

===[alternative - creates 3 array elements - but keeps '\n']====================
array size: 3
0: root:*:0:0:System Administrator:/var/root:/bin/sh

1: daemon:*:1:1:System Services:/var/root:/usr/bin/false

2: _cvmsroot:*:212:212:CVMS Root:/var/empty:/usr/bin/false


===[as list, breaks on IFS (default on spaces too) - more elements as lines]====
array size: 6
0: root:*:0:0:System
1: Administrator:/var/root:/bin/sh
2: daemon:*:1:1:System
3: Services:/var/root:/usr/bin/false
4: _cvmsroot:*:212:212:CVMS
5: Root:/var/empty:/usr/bin/false

===[as previous breaks on IFS, but only on '\n' ]===============================
array size: 3
0: root:*:0:0:System Administrator:/var/root:/bin/sh
1: daemon:*:1:1:System Services:/var/root:/usr/bin/false
2: _cvmsroot:*:212:212:CVMS Root:/var/empty:/usr/bin/false
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the thorough example. I didn't get it fixed though, so I decided to forget about Bash for this task.
@Link OK, it's your decision, but it is a bit strange, because for the file based operations (checking existence of some file) based on a list in the another file is extremelly trivial in bash... Maybe you tooks the problem from the wrong side (arrays and "C/Java" like thinking..). An cleaner question - what you want achieve -, would be lead to more helpful answers. E.g. the autogenerated files has more lines? or only 1 as you show? Have more such files? What to do, if the tiff exists and what if isn't? etc...etc...
0

Why are you creating tLen as an array?

declare -a creates an array, but if you supply single value, it gets assigned to its first element only. To assign a list to the array, you have to enclose the list in parentheses:

TIF_PATH=( $(egrep "INPUT_FILE_DOC_TIF" "${FILE_ARRAY[$@]}" | sed 's#INPUT_FILE_DOC_TIF=##g') )

1 Comment

Good question. I don't actually know why I created tLen as an array. It didn't make a difference changing it, however. I've also tried changing my code to what you suggested, and still no luck. Might it work if I create another for loop, just to iterate TIF_PATH?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.