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.
I want to total up all files created within each minute in the current directory and display the quantities and the final average. I can do the first part by this code (not the best, but it does its job)
Code:
for a in `ls -l | awk --field-separator=" " '{ print $8 }' | sort -u`
do
echo "$a,`ls -l | grep $a | wc -l`"
done
Which gives me output like this:
Code:
09:01,14
09:02,22
...
...
09:22,16
How do I total up the second fields (14, 22, ..., 16, etc.) and create the average and have something like:
1. Do not parse ls, see here for more. the main reason would be the awk you are using will fall in a screaming heap if any file contains white space
2. Why repeat code twice when you can just place it in a variable -- ls -l | grep $a | wc -l
3. You seem to be ok at using awk, so as advised originally, why not use it to do the work you require
4. There would be no need for a temp file if using awk (or one of the other languages suggested)
Well, you learn by experimenting then refining. But thanks for the links, I'll definitely take a look at them.
EDIT: Actually, on the topic on refining, how would this be done totally in awk? I do know awk to a limited level, so this could help improve my knowledge.
Last edited by blenderfox; 07-03-2013 at 07:44 AM.
Interestingly, after looking a little further at your solutions, you do realise that by returning the time portion (which is another reason not to use ls as on my computer $8 is the file name)
that while the time of the file may be '09:01' (from your example) that the actual date could be from any point in time, ie 30.05.2013 09:01 and 03.07.2013 09:01
One would guess that this would not be the desired output ( I could be wrong )
Interestingly, after looking a little further at your solutions, you do realise that by returning the time portion (which is another reason not to use ls as on my computer $8 is the file name)
that while the time of the file may be '09:01' (from your example) that the actual date could be from any point in time, ie 30.05.2013 09:01 and 03.07.2013 09:01
One would guess that this would not be the desired output ( I could be wrong )
Yes, appreciate that might be the case. However this script was meant as a quick fix. Once it worked (which it does), then comes the refining and improving, which all the contributions here are helping with - so thank you all for your comments. I'm not an expert at scripting by any means, and as with most programming and scripting, there's many ways to do the same thing, although some ways are better and/or more efficient. I forgot about the iteration and looping constructs in awk, so I have to thank danielbmartin for that.
I second H_TeXMeX_H's suggestion of using stat. And as a proof of concept you can have a script like this which makes use of associative arrays and exploits default behavior of bash to have indices in arrays to be always sorted:
Code:
#!/bin/bash
[[ BASH_VERSINFO -ge 4 ]] || {
echo "You need at least Bash version 4.0 to run this script." >&2
exit 1
}
declare -a LIST=()
declare -A COUNTS=()
declare -i TOTALFILES=0
for FILE in *; do
if [[ -f $FILE ]]; then
DATESTRING=$(exec stat -c '%y' "$FILE")
DATESTRING=${DATESTRING%:*}
TIMESTAMP=$(exec date -d "$DATESTRING" '+%s')
LIST[TIMESTAMP]="$DATESTRING"
(( ++COUNTS[$DATESTRING] ))
(( ++TOTALFILES ))
fi
done
for I in "${!LIST[@]}"; do
DATESTRING=${LIST[I]}
COUNT=${COUNTS[$DATESTRING]}
echo "Time: $DATESTRING, Count: $COUNT"
done
TOTALTIMES=${#LIST[@]}
AVERAGE10000=$(( TOTALFILES * 10000 / TOTALTIMES ))
if [[ ${#AVERAGE10000} -gt 4 ]]; then
INT=${AVERAGE10000:0:(-4)}
else
INT=0
fi
DEC=0000${AVERAGE10000}; DEC=${DEC:(-4)}
echo "Sum: $TOTALFILES, Avg: $INT.$DEC, Count: $TOTALTIMES"
Additional Note: Following grail's idea I decided to just base it on datetimes instead of just hours and minutes. Also I just based it on the modification time instead of creation time as it seems to be not supported or was disabled on my filesystem, but you could just change the argument to the stat command.
And you need at least version 4.0 of Bash to run the script.
Last edited by konsolebox; 07-04-2013 at 02:27 AM.
@konsolebox - that looks perfect. A lot of extra lines of code compared to the other solutions, but like I said previously, there's always more than one way to do the same thing.
but like I said previously, there's always more than one way to do the same thing.
Obviously, that is why I'm just showing a proof of concept. Yet again, what was it that you really needed at first, and do you plan to change that now? Still, having one good solution I believe this thread could be marked as solved already.
And why do you have to seek for another way? And I don't think you could do that better in Awk, although you could do it better with interpreted languages.
Last edited by konsolebox; 07-04-2013 at 02:33 AM.
Obviously, that is why I'm just showing a proof of concept. Yet again, what was it that you really needed at first, and do you plan to change that now? Still, having one good solution I believe this thread could be marked as solved already.
Yep, will mark it solved. Thanks for all the contributions.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.