[SOLVED] List folder name and time in one line to create a variable in bash
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
List folder name and time in one line to create a variable in bash
Hello
I have this code:
Code:
Please select something to restore [1, 2, 3 e.t.c]:"
# get the folders count
count=$(ls -ltd $INCDIR/*/ | wc -l)
select incvalue in $(ls -ltd $INCDIR/*/ | awk -F/ '{print $(NF-1)}'); do
# if input is a number and is less than or equal to count
if (( $REPLY && $REPLY <= $count )) 2> /dev/null; then
break
else
echo "Your input ${REPLY} is not available. Please select a number from the list:"
fi
I'm not entirely clear of what the scope is of what you're doing, or whether or not you wish to display the time, etc., in the selection list display. I can see that, in your example at least, the date is part of the path to the file; so I realize that you might obtain the date on which someone wishes to focus, outside the scope of the example you've showed us. One way or another, I get the impression that the problem you're having relates to the way select parses things.
I'm particularly confused because this is a "Non-*NIX Forum" and yet you seem to be using things that are *NIX related; even if you're using Cygwin, I would tend to think of it as in some way Unix/Linux related.
I'll show you what I'd think of as a full blown example, and you can always cut it down to focus just on the elements you wish.
sel_restore.bash:
Code:
#!/bin/bash
echo "Please select something to restore [1, 2, 3 e.t.c]:"
# get the folders count
count=$(ls -ltd $INCDIR/* | wc -l)
select incvalue in $(ls -ldt --time-style=+%s $INCDIR/* | gawk -e '{ print strftime( "%a_%b_%e_%H:%M:%S_%Z_%Y" , $6) ":_" $7;}')
do
# if input is a number and is less than or equal to count
if (( $REPLY && $REPLY <= $count )) 2> /dev/null
then
break
else
echo "Your input ${REPLY} is not available. Please select a number from the list:"
fi
done
When I run that script with INCDIR having the value 'a_dir' and "inc" files 1 through 12, I get this:
Code:
./sel_restore.bash
Please select something to restore [1, 2, 3 e.t.c]:
1) Fri_Nov_15_23:28:03_CST_2019:_a_dir/inc_12
2) Fri_Nov_15_23:28:01_CST_2019:_a_dir/inc_11
3) Fri_Nov_15_23:27:59_CST_2019:_a_dir/inc_10
4) Fri_Nov_15_23:27:57_CST_2019:_a_dir/inc_9
5) Fri_Nov_15_23:27:55_CST_2019:_a_dir/inc_8
6) Fri_Nov_15_23:27:53_CST_2019:_a_dir/inc_7
7) Fri_Nov_15_23:27:51_CST_2019:_a_dir/inc_6
8) Fri_Nov_15_23:27:49_CST_2019:_a_dir/inc_5
9) Fri_Nov_15_23:27:47_CST_2019:_a_dir/inc_4
10) Fri_Nov_15_23:27:45_CST_2019:_a_dir/inc_3
11) Fri_Nov_15_23:27:43_CST_2019:_a_dir/inc_2
12) Fri_Nov_15_23:27:41_CST_2019:_a_dir/inc_1
#? 99
Your input 99 is not available. Please select a number from the list:
#?
1) Fri_Nov_15_23:28:03_CST_2019:_a_dir/inc_12
2) Fri_Nov_15_23:28:01_CST_2019:_a_dir/inc_11
3) Fri_Nov_15_23:27:59_CST_2019:_a_dir/inc_10
4) Fri_Nov_15_23:27:57_CST_2019:_a_dir/inc_9
5) Fri_Nov_15_23:27:55_CST_2019:_a_dir/inc_8
6) Fri_Nov_15_23:27:53_CST_2019:_a_dir/inc_7
7) Fri_Nov_15_23:27:51_CST_2019:_a_dir/inc_6
8) Fri_Nov_15_23:27:49_CST_2019:_a_dir/inc_5
9) Fri_Nov_15_23:27:47_CST_2019:_a_dir/inc_4
10) Fri_Nov_15_23:27:45_CST_2019:_a_dir/inc_3
11) Fri_Nov_15_23:27:43_CST_2019:_a_dir/inc_2
12) Fri_Nov_15_23:27:41_CST_2019:_a_dir/inc_1
#? 12
I put underscores in the full blown date and time value to prevent "select" from parsing it into multiple values, as well after the colon between the date time and the filename.
how much control do you have over the naming of the directories ?
if you name them
Code:
mkdir "$( date +%F-%H:%M )_inc_${number}"
the the Dirs will be "globbed" in order
your code can be shrunk to
Code:
PS3="Please select a number from the list:"
select incvalue in $INCDIR/*/
do
if [[ -z $incvalue ]]
then
echo Your input ${REPLY} is not available.
else
[[ $incvalue == quit ]] && exit
echo $incvalue your commands here but not as echo
break
fi
done
now, if you want to complicate things and not name your dirs ( or if you can't )
Code:
#!/bin/bash
INCDIR=/path/to/dirs
GetDirs () {
for i in ${INCDIR}/*/
do
printf "%(%F-%H:%M)T %s\n" \
"$( stat -c %Y "$i" )" \
"$i"
done | sort -r
}
PlaceHolderName () {
local IFS="${IFS:(-1)}"
# I set IFS to be only newline
select incvalue in $( GetDirs )
do
[[ $REPLY =~ ^[qQ]$ ]] && exit
if [[ -z $incvalue ]]
then
echo Your input ${REPLY} is not available.
else
echo $incvalue your commands here but not as echo
echo the Dir is ${incvalue#* }
break
fi
done
}
PlaceHolderName
#
see "man builtins" search for printf
see "man date" for %F-%H:%M explanation
see "man stat"
the trick with IFS would work with your code, if you feel you must do it that way
Edit:. this is just demo code, needs proper checks etc.
oIFS=$IFS
IFS=${IFS:(-1)}
select incvalue in $( ls -ltd $INCDIR/*/ | cut -d\ -f 8- )
do
[[ $REPLY =~ ^[qQ]$ ]] && exit
if [[ -z $incvalue ]]
then
echo Your input ${REPLY} is not available.
else
echo $incvalue your commands here but not as echo
echo the Dir is ${incvalue#* }
break
fi
done
IFS=$oIFS
#
using that code i do not get as output the inc5 and i am getting instead the full path....
Quote:
/backup/folder1/16-11-2019/folder2/inc/inc5/
Quote:
oIFS=$IFS
IFS=${IFS-1)}
select incvalue in $( ls -ltd $INCDIR/*/ | cut -d\ -f 8- )
do
[[ $REPLY =~ ^[qQ]$ ]] && exit
if [[ -z $incvalue ]]
then
echo Your input ${REPLY} is not available.
else
echo $incvalue your commands here but not as echo
echo the Dir is ${incvalue#* }
break
fi
done
IFS=$oIFS
At the end the ${incvalue#* } is not inc5 .... instead i am getting the full path:
use
[code]
your code here
[/code]
instead of [quote][/quote]
Edit: I had the INCDIR hardcoded
reposting
Code:
INCDIR=${1:-.}
oIFS=$IFS
IFS=${IFS:(-1)}
select incvalue in $(ls -ltd ${INCDIR%/}/*/ | cut -d\ -f 8- )
do
[[ $REPLY =~ ^[qQ]$ ]] && exit
if [[ -z $incvalue ]]
then
echo Your input ${REPLY} is not available.
else
echo $incvalue your commands here but not as echo
echo the Dir is ${incvalue#* ${INCDIR%/}/}
# or
incvalue=${incvalue%/}
echo the Dir is ${incvalue##*/}
break
fi
done
IFS=$oIFS
#
but it is rather clumsy
no doubt you will want to work with the selected dir at some point
so the full path would be ${incvalue#* }
the "#* " removes everything up to and including the first space
oIFS=$IFS
IFS=${IFS:(-1)}
select incvalue in $(ls -ltd ${INCDIR%/}/*/ | cut -d\ -f 8- )
do
[[ $REPLY =~ ^[qQ]$ ]] && exit
if [[ -z $incvalue ]]
then
echo Your input ${REPLY} is not available.
else
incvalue=${incvalue%/}
echo the Dir is ${incvalue##*/}
break
fi
done
IFS=$oIFS
Somewhat more involved but you can create an array to look at the desired directories and change it based on what you want to display.
Code:
inclist=( $(ls -ltd ${INCDIR%/}/*/ | cut -d\ -f 8- ) )
for i in "${!inclist[@]}"; do
echo "inclist: $i, value: ${inclist[$i]}"
do some string manipulation here to remove path
inclist[$i]=$new_value
done
select incvalue in "${inclist[@]}"
do
done
INCDIR=${1:-.}
oIFS=$IFS
IFS=${IFS:(-1)}
Dirs=( "$( ls -ltd ${INCDIR%/}/*/ | cut -d\ -f 8- )" )
select incvalue in ${Dirs[@]//${INCDIR%/}\/}
do
[[ $REPLY =~ ^[qQ]$ ]] && exit
if [[ -z $incvalue ]]
then
echo Your input ${REPLY} is not available.
else
echo $incvalue your commands here but not as echo
# echo the Dir is ${incvalue#* ${INCDIR%/}/}
incvalue=${incvalue%/}
echo the Dir is ${incvalue#* }
break
fi
done
IFS=$oIFS
#
there are many ways to do what you ask
it really depends an what is going on with the rest of the script
and is just having the "time" useful? shouldn't you also have the date?
HH:MM isn't much use on its own
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.