JeoSaurus 32 Posting Whiz in Training

It sounds like you already have the Pi, but I got a cubieboard for this purpose because it has an actual SATA port. I've got a 1TB 2.5" drive, powered through the cubieboard (Just make sure your power supply is at least 2amps or better!).

JeoSaurus 32 Posting Whiz in Training

I like to use 'tee' to print the results to the console AND to a file. Also, the "--color=auto" option to grep can help with readability of output, but I'm not sure how well it works in all shells when reading the results from a text file. Try something like this:

grep --color=auto "pattern" /path/to/file.txt | tee -a logfile.txt

I like the idea of using sed to double-space, but you can accomplish the same thing (grep + sed G) in one line of awk:

awk '/pattern/ {print $0 "\n"}' /path/to/file.txt

I hope this helps!
-G

LaxLoafer commented: Well done Gromit :-) +3
JeoSaurus 32 Posting Whiz in Training

Neat! Do you want the date to be updated each time? In your code snippet, you run the 'date' command one time, so each entry will be the same date/time. Try something like this!

#!/bin/sh
for i in $(seq 1 600); do
    date |tee -a outputfile
    sleep 1
done

Or if you're using bash:

#!/bin/bash
for i in {1..600}; do
    date |tee -a outputfile
    sleep 1
done

That should give you the results you need, and print them to the console at the same time it's writing to the output file. If you don't need the date to be current for each iteration, you can just set your date variable first, like in your example:

#!/bin/bash
dt=$(date)
for i in {1..600}; do
    echo $dt |tee -a outputfile
    sleep 1
done

I hope this helps!

Baduizm commented: Yeah +0
JeoSaurus 32 Posting Whiz in Training

Cut works well for that! Or awk:

echo $file | awk -F/ '{print $3}'

You could also do something with sed...

echo $file | sed -n 's%/media/\([^/]*\)/.*%\1%p'

HTH!
-G

JeoSaurus 32 Posting Whiz in Training

/etc/rc.local is a good place to put simple scripts that you want executed at boot-time. Lines in rc.local are executed as root (unless specified otherwise) and after all the other startup scripts have run.

JeoSaurus 32 Posting Whiz in Training

Oh, right! Not all versions of grep have the -A and -B flags. Here's a definition:

-A NUM, --after-context=NUM
      Print  NUM  lines of trailing context after matching lines.  Places a line containing -- between con-
      tiguous groups of matches.

-B NUM, --before-context=NUM
      Print NUM lines of leading context before matching lines.  Places a line containing --  between  con-
      tiguous groups of matches.

There's a way to do this with sed, but I haven't sat down with it to break it down and understand it myself. Here's a link to the O'reilly Unix Power Tools page that talks about it: http://docstore.mik.ua/orelly/unix3/upt/ch13_09.htm

And here's a link to the 'cgrep' script that they use in the example: http://examples.oreilly.com/9780596003302/example_files.tar.gz

I hope this helps!

4evrmrepylrning commented: Much appreciated! +1
JeoSaurus 32 Posting Whiz in Training

If you are pasting into vi, you might try running ":set paste" in vi before hitting insert and pasting.

JeoSaurus 32 Posting Whiz in Training

Hello iamthesgt!

I'm sure there's some standard way to do this, but I don't know it. There are lots of pre-existing scripts out there that are similar to this one, but here's something I have been using for a while:

#!/bin/bash

# Check for FreeBSD in the uname output
# If it's not FreeBSD, then we move on!
if [ "$(uname -s)" == 'FreeBSD' ]; then
  OS='freebsd'

# Check for a redhat-release file and see if we can
# tell which Red Hat variant it is
elif [ -f "/etc/redhat-release" ]; then
  RHV=$(egrep -o 'Fedora|CentOS|Red.Hat' /etc/redhat-release)
  case $RHV in
    Fedora)  OS='fedora';;
    CentOS)  OS='centos';;
   Red.Hat)  OS='redhat';;
  esac

# Check for debian_version
elif [ -f "/etc/debian_version" ]; then
  OS='debian'

# Check for arch-release
elif [ -f "/etc/arch-release" ]; then
  OS='arch'

# Check for SuSE-release
elif [ -f "/etc/SuSE-release" ]; then
  OS='suse'

fi

# echo the result
echo "$OS"

It probably needs to be updated, and if you want to get more granular (debian vs ubuntu) or go as far as specific versions for each distro, it'll require a bit more than what's here. Hopefully, though, this will get you started.

-G

JeoSaurus 32 Posting Whiz in Training

Hi!

It looks like you're off to a good start! Since it's homework, I won't make any suggestions about doing it a different way, but I can point out some things that I can definitely see that might trip you up in the troubleshooting process!

First: when you want to execute a command and do something with the output, don't use [square brackets], just use the $(commands go here) style. Square brackets indicate that you want to do some kind of evaluation (true/false) of the output.

Second: you go to the trouble of setting the "$g" variable, but then you call "$@" again a few lines down, when I assume you just want to work with one value of $@ per loop. Try using "$g" in your evaluation of "if $groupname=$g".

Third: This is the real clue to what's happening, I think! You're working with cut, which is giving you whole columns of data, but you really only need one row out of that column of data for each iteration of "$g". Try using 'awk' or 'grep' to narrow down the results ;)

Once you've tweaked those three things, I think you'll be much closer to a working script. I'm not sure about the logic in the loop where you're calculating $count, but I think when you resolve the three things above, the rest should be easier to sort out.

One more hint... all those numbers might be getting printed to stderr instead of stdout... try redirecting stderr to /dev/null, …

iamthesgt commented: Thanks for the help. +3
JeoSaurus 32 Posting Whiz in Training

Hi gedas,

This script takes the INPUT file as a command line argument using the "shift" function here: my $infile = shift; The OUTPUT file name is also taken from the command line, OR generated by tacking on ".xls" on the end of the input filename: my $outfile = shift || $infile . ".xls"; Try running the script with no arguments to get some 'usage' hints (Or you could read it directly from the 'usage' function in the script!)

I hope this helps!

JeoSaurus 32 Posting Whiz in Training

Hello voidyman!

I'm not sure about kicking off a process via FTP, but if you have cron access you might get better results running a shell script from cron that checks for that file, and does the work if it exists.

JeoSaurus 32 Posting Whiz in Training

Hi voidyman!

I'm not sure how you got those fonts in here, but it sure makes your post hard to read!

A quick check of your script with 'perl -c' shows that the script (at least what you've pasted here) is missing a curly bracket at the end of the file (for that big "for(my $iSheet..." loop).

Another thing that *might* be an issues is the 'use XLSX.pm;' line. If that's a module you're including locally, try it without the '.pm' extension (use XLSX;)

I hope this helps!

JeoSaurus 32 Posting Whiz in Training

Interesting! One way I was able to reproduce that is with an extra line at the end of the input file. Here's a successful run:

-> cat -E test.txt 
1 0 100$
2 11 150$
3 0 189$
4 0 195$
5 21 245$

-> python test.py 
0
11 non-zero!
0
0
21 non-zero!
Non-zero total: 2

Here's a run with an extra line at the end of the csv file:

-> echo >> test.txt

-> cat -E test.txt 
1 0 100$
2 11 150$
3 0 189$
4 0 195$
5 21 245$
$

-> python test.py 
0
11 non-zero!
0
0
21 non-zero!
Traceback (most recent call last):
  File "test.py", line 9, in ?
    print row[1],
IndexError: list index out of range

So you might want to look at a way to check the input and trim out any blank lines, if there are any. It could also be something else entirely!...

Here's a simple example that checks to see if the list is empty before trying to process it:

#!/usr/bin/python
 
import csv
 
csvInput = csv.reader(open('test.txt', 'rb'), delimiter=' ')
count = 0
 
for row in csvInput:
    if row:
        print row[1],
        if row[1] != "0":
            print "non-zero!"
            count += 1
        else:
            print
 
print "Non-zero total: %s" % count

Again, I'm terrible at python, but I hope this helps! :)
-G

vegaseat commented: nice effort +15
JeoSaurus 32 Posting Whiz in Training

Hello yli!

Are you trying to replace values or strings? In your example, you're using str_replace() which gives us interesting results. For instance: "portocala" becomes "portoc<b>ala</b>"

For THIS example, I'll assume that's what you're expecting! :)

You can replace your new_kw/old_kw logic with a simple loop, which will loop through that array, no matter how many elements there are:

<?php

$search = "ala salsa portocala nueve vacas";
$where  = "texto ala salsa nueve texto portocala verde nueve";

$old_kw = explode(" ",$search);

foreach ($old_kw as $key => $value) {
   $new_kw[$key] = "<b>$value</b>";
}

$where  = str_replace($old_kw, $new_kw, $where);

echo "$where\n";

?>

I get the following output, which is identical to what I was getting from the original script:

texto <b>ala</b> <b>salsa</b> <b>nueve</b> texto portoc<b>ala</b> verde <b>nueve</b>

I hope this helps! Let us know if this isn't what you were looking for, and we'll see what we can do :)
-G

JeoSaurus 32 Posting Whiz in Training

Hello Sid!

I don't think there's a way to accomplish this with pure PHP. If cron is available on the server (if it's a unix/linux system, or task scheduler if it's Windows), that's probably the way to go.

I hope this helps!
-G

JeoSaurus 32 Posting Whiz in Training

Hi all! This can be done with a fairly simple one-liner!

As Salem pointed out, all the clues are in the man page, but I personally found the solution in 'sort' rather than 'uniq':

# The test file with your sample data
-> cat test.txt 
REF | FOR | SUR
TLT090991|STEPHEN|GRIFFITHS
TLT090992|STEPHEN|GRIFFITHS

#Test run with one-line sort command
-> sort -t\| -k2 -u test.txt 
REF | FOR | SUR
TLT090991|STEPHEN|GRIFFITHS

A trip through the man page for 'sort' reveals the following:

-t, --field-separator=SEP
use SEP instead of non-blank to blank transition

-k, --key=POS1[,POS2]
start a key at POS1, end it at POS2 (origin 1)

-u, --unique
with -c, check for strict ordering; without -c, output only the first of an equal run


TL;DR version:
-t sets the field separator, in this case "|" (escaped with \)
-k tells it which field to start with
-u says only print out unique lines (taking into consideration our starting position)

I hope this helps!
-G

JeoSaurus 32 Posting Whiz in Training

Hi Freude!

The ">" basically just re-directs output. In this case, the result of: echo "pause 1; replot; reread;" > loop_forever.gnu would be a file named 'loop_forever.gnu' with the stuff in quotes as the content of the file.

It looks like .gnu is an extension to indicate that it's a gnuplot script.

Beyond that, I'm not familiar with gnuplot, so I don't know how much more I can help, but let us know if you have more questions!

Thanks!
-G

JeoSaurus 32 Posting Whiz in Training

Hello landog!

I'm not sure exactly where that particular error comes from, but there are a couple of issues with this.

First, when comparing integers you'll want to use the '-eq' operator. Use '=' to compare strings. I think '==' won't work in some shells.

Second, your 'if' statement is enclosed in an extra set of [brackets]. Knock those off and we're one step closer!

Third, and I could be wrong about this, but 'if' won't do math for you. The way to express a math problem in bash is $((x+y)) (or $(($x+$y)) ).

The 'Advanced Bash Scripting Guide' on the tldp.org site is just about the best bash scripting reference out there. Here's a link to the page on operators:

http://tldp.org/LDP/abs/html/comparison-ops.html

Here's a working example (in my shell anyway) of what I think you're trying to express:

#!/bin/bash

a=1
b=1
c=2

if [ $a -eq $((b+c)) ] || [ $b -eq $((a+c)) ] || [ $c -eq $((a+b)) ]; then
   echo 'Looks OK!'
else
   echo 'No Match :-('
fi

In this case the third expression should be true, triggering the 'Looks Ok!' result.

I hope this helps!
-G

JeoSaurus 32 Posting Whiz in Training

You might want to give 'ls' a try! In my test (using your script) 'ls' returned just filenames.

use Net::FTP;
$ftp = Net::FTP->new("mysite.com");
$ftp->login('xxxx', 'xxxx');
$ftp->cwd("/private/test");
my @filenames=$ftp->ls();
$ftp->quit;
foreach (@filenames){
  print "$_\n";
}

This results in the output:

$ perl test.pl 
test5.txt
test4.txt
test2.txt
test1.txt
test3.txt

My ftp server doesn't even recognize an 'nlst' command.
I hope this helps!
-G

winky commented: Went above and beyond. +4
d5e5 commented: Good test. +2
JeoSaurus 32 Posting Whiz in Training

Well both of those methods are imperfect for counting connections, but you're probably getting a more accurate result with grep in this case, because it won't count the first two lines (if your output is like mine)

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State

Also consider that the result may actually be different from one moment to the next.

Here's perhaps a more accurate way to do it:

echo "TCP Connections: $(netstat -ant|awk 'END {print NR-2}')"
echo "UDP Connections: $(netstat -anu|awk 'END {print NR-2}')"

OR I like to do things where we're getting multiple numbers from the same output, in more of a snapshot form since the numbers CAN change from one moment to the next. Something like this may be more appropriate, depending on the ultimate goal of your script:

NETSTAT=$(netstat -an)
echo "TCP: $(echo "$NETSTAT"|grep -c ^tcp)"
echo "UDP: $(echo "$NETSTAT"|grep -c ^udp)"
rch1231 commented: The awk and grep examples were great and I had never used the output to a variable like that. Well written. +2
JeoSaurus 32 Posting Whiz in Training

This post is 2 days old, so I hope this helps...

There are some commands that are actually made for this! Try "host" or "nslookup". Your results will be much faster and easier to parse than ping.

-G

JeoSaurus 32 Posting Whiz in Training

Hmm... well, technically you could run it all on one line like this: for FILE in $(find . -type f -name '*4%3a*'); do NEWNAME=$(echo $FILE|sed s/'4%3a'//); mv -v $FILE $NEWNAME; done but that's kind of ugly :-P

What we have here is called a shell script. What you'll probably want to do is paste the script from above into a text file. Name that text file "myrename.sh" or something easy to remember. Copy it into your ~/bin directory, or if this is a temporary project, save it in the directory where all those files live, and execute it like: $ sh /path/to/myrename.sh I hope that's not too confusing.
-G

bimaljr commented: Perfect sollution +2