I have a bash script that ask the person to first select an order at which the files in the current directory are displayed. Next I have them choose a file from a list that is created using a select loop. After they select a file it will ask them what type of command they would like to use. My issue is that I want to display only a certain number of files to the user at a time. Let's say I want to list 23 files at a time. How would I do that?
Sorry if it is sloppy
ORDER=("name" "age" "size")
select OPT4 in "${ORDER[@]}"
do
if [[ $OPT4 == "name" ]]
then
ARRAY=( $( ls . ) )
# select OPT2 in "${ARRAY[@]}"
# do
# echo $OPT2
# done
fi
if [[ $OPT4 == "age" ]]
then
ARRAY=( $( ls -rt ) )
# select OPT2 in "${ARRAY[@]}"
# do
# echo $OPT2
# done
fi
if [[ $OPT4 == "size" ]]
then
ARRAY=( $( ls -S ) )
# select OPT2 in "${ARRAY[@]}"
# do
# echo $OPT2
# done
fi
echo $OPT4
#ARRAY=( $( ls -S ) )
select OPT2 in "${ARRAY[@]}"
do
OPTIONS=("author" "type" "copy" "ren" "move" "del" "copy!" "ren!" "move!" "help")
select OPT1 in "${OPTIONS[@]}"
do
if [[ $OPT1 == "copy!" || $OPT1 == "move!" || $OPT1 == "ren!" ]]
then
select OPT3 in "${ARRAY[@]}"
do
echo $OPT3
break
done
fi
if [[ $OPT1 == "copy" || $OPT == "move" || $OPT1 == "ren" ]]
then
echo -n "Enter a file destination: "
read OPT3
fi
case $OPT1 in
$AUTHOR)
echo "Last, First";;
$TYPE)
exist
file
order66;;
$COPY)
exist
file
order66;;
$RENAME)
# mv &>/dev/null $2 $3;;
exist
file
order66;;
$MOVE)
# mv &>/dev/null $2 $3;;
exist
file
order66;;
$DELETE)
# rm -f &>/dev/null $2;;
exist
file
order66;;
$FORCE_COPY)
exist
file
order67;;
$FORCE_MOVE)
exist
file
order67;;
$FORCE_RENAME)
exist
file
order67;;
$HELP)
echo -e $MESSAGE;;
*)
echo -e $MESSAGE;;
esac
exit
done
done
done
Your best solution is to read the list of files into an array, and then implement a simple pager. You can then use a c-style for loop
to keep track of the file indexes and act on the value of the loop index. The following shows implementation of the pager. What you will do to act on the index is just add to the read statement (eg: read -p "(#)Select File (f)orward (b)ack : " ans
) and include an else
to handle the #
). I've posted the additional code for filename selection below the pager example.
The number of files shown per-page is controlled with the pg_size
variable. Adjust as necessary. Likewise, you can control whether files are read recursively by adjusting the find
statement filling the file array:
#!/bin/bash
declare -i pg_size=4
file_array=( $(find "$1" -maxdepth 1 -type f) )
for ((i=0; i<${#file_array[@]}; i++)); do
echo " ${i}. ${file_array[$i]}"
if [ "$i" -gt 0 -a $(((i+1)%pg_size)) -eq 0 ]; then
read -p "(f)orward (b)ack : " ans
if [ "$ans" = 'b' ]; then
[ "$i" -gt "$((pg_size))" ] && ((i = i - (2*pg_size))) || ((i = i - pg_size))
fi
fi
done
output example:
$ ./lspager.sh tmp
0. tmp/File1950text.doc
1. tmp/vcs1dump
2. tmp/File2014text.xls
3. tmp/File307list.cvs
(f)orward (b)ack : b
0. tmp/File1950text.doc
1. tmp/vcs1dump
2. tmp/File2014text.xls
3. tmp/File307list.cvs
(f)orward (b)ack : f
4. tmp/vcsa1dump
5. tmp/File256name.txt
6. tmp/README.txt
7. tmp/dl
(f)orward (b)ack : b
0. tmp/File1950text.doc
1. tmp/vcs1dump
2. tmp/File2014text.xls
3. tmp/File307list.cvs
(f)orward (b)ack : f
4. tmp/vcsa1dump
5. tmp/File256name.txt
6. tmp/README.txt
7. tmp/dl
(f)orward (b)ack : f
8. tmp/File1949text.doc
9. tmp/vcsadump
10. tmp/vcsdump
11. tmp/helloworld.txt
(f)orward (b)ack : f
12. tmp/File1951text.dat
To implement the filename selection, simple add to the read
and implement a test to validate a numeric answer within range and break out of the loop:
#!/bin/bash
declare -i pg_size=4
file_array=( $(find "$1" -maxdepth 1 -type f) )
for ((i=0; i<${#file_array[@]}; i++)); do
echo " ${i}. ${file_array[$i]}"
if [ "$i" -gt 0 -a $(((i+1)%pg_size)) -eq 0 ]; then
read -p "(#)Select file (f)orward (b)ack : " ans
if [ "$ans" = 'b' ]; then
[ "$i" -gt "$((pg_size))" ] && ((i = i - (2*pg_size))) || ((i = i - pg_size))
elif [[ "$ans" =~ [0-9] ]]; then # note character class, [[, and =~ are bash only
[ "$ans" -le "$i" ] && echo "You chose '$ans' - ${file_array[$ans]}" && break
fi
fi
done
output:
$ ./lspager.sh tmp
0. tmp/File1950text.doc
1. tmp/vcs1dump
2. tmp/File2014text.xls
3. tmp/File307list.cvs
(#)Select file (f)orward (b)ack : f
4. tmp/vcsa1dump
5. tmp/File256name.txt
6. tmp/README.txt
7. tmp/dl
(#)Select file (f)orward (b)ack : f
8. tmp/File1949text.doc
9. tmp/vcsadump
10. tmp/vcsdump
11. tmp/helloworld.txt
(#)Select file (f)orward (b)ack : b
4. tmp/vcsa1dump
5. tmp/File256name.txt
6. tmp/README.txt
7. tmp/dl
(#)Select file (f)orward (b)ack : 5
You chose '5' - tmp/File256name.txt
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.