Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place. |
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.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
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.
|
|
09-04-2007, 12:32 PM
|
#1
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852
|
bash syntax: looping through a comma-separated list
How can I get bash to read a list of inputs one at a time?
I'm trying to process some video and I would like to run the same command at predetermined intervals on the file. I'd like to use a comma-delineated list of timestamps as the input. I want to do something like this:
for TIME in "time1,time2,time3,time4" ; do command @ $TIME ; done
But I can't figure out how to get bash to process such a list. I tried looking at the 'read' command, but I even figure out exactly what it's supposed to do, or whether it would apply in this case. I've found a way to input the times via a text file (using the 'line' command), but it's a big hassle since I have to edit the list so that there's one entry per line. There must be a way to use the list as-is. I've searched this forum and this web but haven't found anything useful.
I want to be able to do this both from the command prompt and eventually through an actual script. Can someone help me out here?
PS: As a related question, is there any easy way to generate a list of regularly spaced timestamps, say every 300 seconds, with the format "hh:mm:ss"?
|
|
|
09-04-2007, 12:51 PM
|
#2
|
Senior Member
Registered: Sep 2005
Location: Out
Posts: 3,307
Rep:
|
Something like that?
1)
IFS=","
var="a,b,c"
for v in $var
do echo "$v"
done
2)
while /bin/true; do sleep 300; date +"%H:%M:%S"; done
|
|
|
09-04-2007, 12:56 PM
|
#3
|
LQ Guru
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509
|
Quote:
Originally Posted by David the H.
I've found a way to input the times via a text file (using the 'line' command), but it's a big hassle since I have to edit the list so that there's one entry per line.
|
This can be done as in
Code:
> echo a,b,c,d | sed s/,/\\n/g
a
b
c
d
|
|
|
09-04-2007, 01:35 PM
|
#4
|
Moderator
Registered: May 2001
Posts: 29,415
|
...and with a default IFS "for v in ${var//,/ }"?
|
|
|
09-04-2007, 01:45 PM
|
#5
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852
Original Poster
|
Quote:
Originally Posted by nx5000
Something like that?
1)
IFS=","
var="a,b,c"
for v in $var
do echo "$v"
done
|
Ok, this seems to work. I had to look up what IFS is. Interesting. But it still seems a bit sloppy though. Wouldn't I have to manually unset the ISF variable after I finished with it, or risk having it interfere with other shell uses? Is there no way to feed the list in directly, without having to resort to a variable or file?
Quote:
2)
while /bin/true; do sleep 300; date +"%H:%M:%S"; done
|
This doesn't seem to do what I want. This generates a list of real-time timestamps. I just want to create a count of 5 minute intervals from 00:00:00 up to, say 01:30:00 (for example).
@colucix: Thank you. That does make converting the list between formats easier. But I'd still like to avoid having to use a text file altogether.
|
|
|
09-04-2007, 01:51 PM
|
#6
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852
Original Poster
|
unSpawn, I just tried your string, but that doesn't seem to work. It only removes the commas, concatenating all the values together into a single long one.
|
|
|
09-04-2007, 03:17 PM
|
#7
|
LQ Guru
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509
|
Quote:
Originally Posted by David the H.
I just want to create a count of 5 minute intervals from 00:00:00 up to, say 01:30:00 (for example).
|
To generate a list of times, I'd suggest to use a while loop, and increase time accordingly to the choosen timestep, like this:
Code:
#/bin/bash
# --------------------------------------------------
# Initialize counter
# --------------------------------------------------
min=0
# --------------------------------------------------
# Loop from 0 to 90 every 5 minutes
# --------------------------------------------------
while [ $min -le 90 ] ; do
time=`date -d "00:00:00 $min minutes" +%H:%M:%S`
echo $time
min=$((min + 5))
done
The date command in linux is very flexible and let to output any date (not only "now") absolute or relative. See info date for details. Cheers!
Last edited by colucix; 09-04-2007 at 03:21 PM.
|
|
|
09-04-2007, 07:32 PM
|
#8
|
Member
Registered: Mar 2007
Location: Bedford, Texas
Posts: 31
Rep:
|
Based on your original question here are a couple of ideas:
The shell for command looks for white space between entries and you could use this for example:
for x in time1 time2 time3 do ; <script> ; done
or you can put the entries in a file and have linux execute a shell command to read the file. For example if you have a list of the times in a file called dotimes and you want the for statement to read the list you could use the back quote (just to the left of the 1 key).
for x in `cat dotimes` do ; <script> ; done
as a bash script you could call it would look like this:
#!/bin/bash
for x in `cat /home/me/dotimes`
do
<script>
done
But the simplest way I can think of to do something like what you want is to run a simple loop with the sleep command. Say you want to list the contents of the /var/tmp directory every 5 minutes to see if the file is growing. From the command line you would type the following:
while true
do
date
/bin/ls -la /var/tmp
sleep 300
done
The command would run every 5 minutes till you stop (break AKA <CTRL> C) it. It would list the date at the beginning of each run so you could see the time change.
Hope this helps.
rhoward1231@yahoo.com
|
|
|
09-05-2007, 05:50 AM
|
#9
|
Senior Member
Registered: Sep 2005
Location: Out
Posts: 3,307
Rep:
|
Quote:
Wouldn't I have to manually unset the ISF variable after I finished with it, or risk having it interfere with other shell uses?
|
If you put the code I posted _in a script_ (and not directly in your current shell) then as a normal script, bash will create a new subshell, execute the script and then return to the parent shell. Then nothing is kept.
If you do it from the command line then yes, you have to set it back,maybe like this:
old_IFS=${IFS}
blabah
IFS=${old_IFS}
Well, it's not that tricky I think. Otherwise unSpawn method is shorter but you need to be using bash, it's not POSIX compliant.
Code:
$ echo $0
/bin/bash
$ var="a,b,c" ; for v in ${var//,/ }; do echo $v; done
a
b
c
$ /bin/sh
$ echo $0
/bin/sh
$var="a,b,c" ; for v in ${var//,/ }; do echo $v; done
/bin/sh: Syntax error: Bad substitution
|
|
|
09-05-2007, 12:50 PM
|
#10
|
Moderator
Registered: May 2001
Posts: 29,415
|
Quote:
Originally Posted by David the H.
unSpawn, I just tried your string, but that doesn't seem to work. It only removes the commas, concatenating all the values together into a single long one.
|
Hmm, maybe you didn't add the space after the slash or you're not using Bash?
|
|
|
09-06-2007, 11:23 AM
|
#11
|
Bash Guru
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852
Original Poster
|
Thanks for the advice everyone. Sorry I couldn't get back to you for a couple of days. There's a lot I have to reply to.
colucix: Now that appears to do just what I was looking for. A bit of modification to add some user inputs and that script will be perfect for generating various lists of timestamps.
rch1231: A-ha, I see. So it's the comma separation that's doing it. The reason I've been using commas is because that's how all the dvd authoring programs handle their chapter lists, and I've just been copy/pasting the numbers. But now I can generate my own lists or use the IFS setting or unSpawn's method to work around it. Speaking of which...
unSpawn: You were right, I did miss the space. It's always the little typos that get you, isn't it? It works when I type it in correctly. I'll probably go with that, since I don't have to worry about setting external variables that way.
nx5000: That's what I thought. I want to be able to do this both with a script and quick-&-dirty manually, so I want to be careful about the IFS setting when I'm doing the latter. And no worries about compatibility. I'll only be using bash.
I appreciate all the help. Now to implement what I've learned.
|
|
|
All times are GMT -5. The time now is 06:15 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|