I want to iterate over an array of file names stored in files_arr
to create a terminal-based file manager in the POSIX shell.
A reduced version of the functions list_directory
looks like this:
# Presents the user with the files in the directory
list_directory() {
# Iterate over each element in array `files_arr` by index, not by filename!
# And outputs the file name one on each line
for file in "${!files_arr[@]}"; do
echo "${files_arr[file]}"
done
}
I want to implement a way to exclude the first n
files from the array files_arr
.
n
is defined by how often the user scrolls past the current terminal window size to create an effect of scrolling through the files, highlighting the file where the cursor is currently on.
On a directory (e.g. the home directory) that looks like this:
To Implement this I try to create an C-like for loop like so:
for ((file=$first_file; file<=${!files_arr[@]}; file=$((file 1))); do
or as the whole function:
# Presents the user with the files in the directory
list_directory() {
# Iterate over each element in array `files_arr` by index, not by filename!
#for file in "${!files_arr[@]}"; do
for ((file=$first_file; file<=${!files_arr[@]}; file=$((file 1))); do
# Highlighted file is echoed with background color
if [ $file -eq $highlight_index ]; then
echo "${BG_BLUE}${files_arr[file]}${BG_NC}"
# Colorize output based on filetype (directory, executable,...)
else
if [ -d "${files_arr[file]}" ]; then
echo "$FG_DIRECTORY${files_arr[file]}$FG_NC"
elif [ -x "${files_arr[file]}" ]; then
echo "$FG_EXECUTABLE${files_arr[file]}$FG_NC"
else
echo "${files_arr[file]}"
fi
fi
# $LINES is the terminal height (e.g. 23 lines)
if [ "$file" = "$LINES"]; then
break
fi
done
}
which returns the error:
./scroll.sh: line 137: syntax error near `;'
./scroll.sh: line 137: ` for ((file=$first_file; $file<=${!files_arr[@]}; file=$((file 1))); do'
How can I iterate over the array files_arr
, defining the start-index of $file
?
CodePudding user response:
You can iterate over the array with:
for (( i = $first_file; i < ${#files_arr[@]}; i )); do
echo ${files_arr[i]}
done
but it seems cleaner to use:
for file in ${files_arr[@]:$first_file}; do
echo "$file"
done