LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-05-2008, 06:51 PM   #1
blckleprd
LQ Newbie
 
Registered: Jun 2008
Posts: 2

Rep: Reputation: 0
[bash] How do I nest for arrays?


So I'm working on a system that does some folder renaming once a week, and I wanted to make the folder dates prettier by changing "1" to "1st", "4" to "4th", etc. I need to do this to two separate arrays, but I couldn't get bash to play nice with my nested for loops. Here's what works:

Code:
#!/bin/bash
# Let's populate an old date array!
oldDates[0]=$(date -v "-4d" "+%A, %B %d"); # Get the date 4 days ago (Last Monday).
oldDates[1]=$(date -v "-2d" "+%A, %B %d"); # Get the date 5 days from now (Last Wednesday).
oldDates[2]=$(date -v "-1d" "+%A, %B %d"); # Get the date 6 days from now (Last Thursday).
oldDates[3]=$(date "+%A, %B %d"); # Get today's date (Friday).
oldDates[4]=$(date -v "+3d" "+%A, %B %d"); # Get the date 3 days from now (Next Monday).

# Let's populate a new date array!
newDates[0]=$(date -v "+3d" "+%A, %B %d"); # Get the date 3 days from now (Next Monday).
newDates[1]=$(date -v "+5d" "+%A, %B %d"); # Get the date 5 days from now (Next Wednesday).
newDates[2]=$(date -v "+6d" "+%A, %B %d"); # Get the date 6 days from now (Next Thursday).
newDates[3]=$(date -v "+7d" "+%A, %B %d"); # Get the date 7 days from now (Next Friday).
newDates[4]=$(date -v "+10d" "+%A, %B %d"); # Get the date 10 days from now (2nd Monday).

for index in 0 1 2 3 4; do # Let's make these dates prettier!
	oldDates[index]=${oldDates[index]// 0/ }th; # Get rid of padding zeros, and add "th" to the end.
	oldDates[index]=${oldDates[index]//1th/1st}; # Replace "1th" with "1st"
	oldDates[index]=${oldDates[index]//11st/11th}; # Replace "11st" with "11th"
	oldDates[index]=${oldDates[index]//2th/2nd};  # Replace "2th" with "2nd"
	oldDates[index]=${oldDates[index]//12nd/12th}; # Replace "12nd" with "12th"
	oldDates[index]=${oldDates[index]//3th/3rd}; # Replace "3th" with "3rd"
	oldDates[index]=${oldDates[index]//13rd/13th}; # Replace "13rd" with "13th"
        echo ${oldDates[index]};
done;

for index in 0 1 2 3 4; do # That was so much fun, let's do it again!
	newDates[index]=${newDates[index]// 0/ }th; # Get rid of padding zeros, and add "th" to the end.
	newDates[index]=${newDates[index]//1th/1st}; # Replace "1th" with "1st"
	newDates[index]=${newDates[index]//11st/11th}; # Replace "11st" with "11th"
	newDates[index]=${newDates[index]//2th/2nd};  # Replace "2th" with "2nd"
	newDates[index]=${newDates[index]//12nd/12th}; # Replace "12nd" with "12th"
	newDates[index]=${newDates[index]//3th/3rd}; # Replace "3th" with "3rd"
	newDates[index]=${newDates[index]//13rd/13th}; # Replace "13rd" with "13th"
        echo ${newDates[index]};
done;
exit 0;
I should be able to compress those two for loops at the end into one for loop, but I can't get it to work. I've attached code to generate the arrays too, so you can just run the entire script to see what it does. I've had the loops echo the dates that it prettifies to make it a bit easier too.

Any help simplifying the two loops or the code in there loops would be great. I know there's a better way to do this, I just couldn't figure it out. Thanks!

Last edited by blckleprd; 06-05-2008 at 07:29 PM.
 
Old 06-05-2008, 08:31 PM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,361
Blog Entries: 55

Rep: Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547Reputation: 3547
This may be cheating a bit but how about:
Code:
#!/bin/bash
_date() { arg="$1"; arg="${arg:0:1} ${arg:1}"; var=$(date --date "${arg} days" '+%d')
 case $var in *1) var="${var}st";; *2) var="${var}nd";; *3) var="${var}rd";;
*) var="${var}th";; esac; var="$(date --date "${arg} days" "+%A$PACK%B")$PACK${var}$PACK"; echo -en ${var// /$PACK}$PACK; }
array=( $(PACK='|'; for n in -3 -2 -1 +0 +3; do _date $n; done|xargs) $(PACK=','; for n in +3 +5 +6 +7 +10; do _date $n; done) )
array0=( ${array[0]//||/ } ); echo array[0] ${array[0]}; echo oldDates ${array0[@]}; echo oldDates[1] ${array0[1]//|/ }
exit 0;
BTW I disagree with the reason for this: IMHO folder dates aren't meant to be "pretty", just functional.
 
Old 06-05-2008, 08:47 PM   #3
blckleprd
LQ Newbie
 
Registered: Jun 2008
Posts: 2

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by unSpawn View Post
BTW I disagree with the reason for this: IMHO folder dates aren't meant to be "pretty", just functional.
I'm writing this for Mac OSX (Sorry, I should have mentioned that), so i don't get GNU date, which really sucks.

If I was coding this just for something I was going to use, I wouldn't bother with pretty dates, but this is to handle naming of folders that others (who aren't very computer savvy unfortunately) are going to have to interact with, hence the required prettiness.
 
Old 06-05-2008, 11:49 PM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,255

Rep: Reputation: 1420Reputation: 1420Reputation: 1420Reputation: 1420Reputation: 1420Reputation: 1420Reputation: 1420Reputation: 1420Reputation: 1420Reputation: 1420
@unSpawn: Did you type that code with your eyes closed?

I don't think this is a case for nested loops, but perhaps some eval trickery:
Code:
prettify-dates ()
{   
    eval indices="\${!$1[@]}"
    for index in $indices ; do # Let's make these dates prettier!                                                                                                                                                  
        eval "uglydate=\${$1[$index]}"
        case $uglydate in
            *01) eval "$1[index]=\${uglydate/01/1st}";;
            *02) eval "$1[index]=\${uglydate/02/2nd}";;
            *03) eval "$1[index]=\${uglydate/03/3rd}";;
            *) eval "$1[index]=\${uglydate/ 0/}th";;
        esac
        eval echo "\${$1[index]}";
    done;
}

prettify-dates oldDates
prettify-dates newDates
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
bash: Passing arrays with spaces jakeo25 Programming 8 06-05-2009 09:00 AM
Bash - How can you list 2 arrays in columns zak111 Programming 12 07-23-2007 12:27 PM
bash arrays question introuble Programming 1 05-20-2006 04:07 AM
Generating iteratable arrays in bash d00bid00b Programming 4 08-15-2005 05:54 PM
bash for statement with 2 arrays? Noerr Linux - General 10 05-27-2002 01:58 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:21 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration