Issue in executing a command in perl - perl

I have the below code:
chdir glob "/home/test/test1/test2/perl*";
#testList = exec "cat test.in | grep build | awk '{print \$2}'";
foreach my $testList(#testList) {
chdir "/home/test/test1/$testList";
exec "cat test.out | grep -w 'PASSED'";
}
After I run the above code, it gives the output for only the below:
chdir glob "/home/test/test1/test2/perl*";
#testList = exec "cat test.in | grep build | awk '{print \$2}'";
but not the other two lines below. I only want the output for the lines:
foreach my $testList(#testList) {
chdir "$opts->{/home/test/test1$testList";
exec "cat test.out | grep -w 'PASSED'";
and not
chdir glob "/home/test/test1/test2/perl*";
#testList = exec "cat test.in | grep build | awk '{print \$2}'";
Please help.

exec and system are returning exit code.
Try:
#testList = `cat test.in | grep build | awk '{print \$2}'`;

Related

Resolve name by inode in current direcory

How can I resolve the name by the given inode in the current directory in the following script that prints all filenames of symlinks pointing to a specified file that is passed as an argument to the script. The list should be sorted by ctime.
#!/usr/bin/ksh
IFS="`printf '\n\t'`"
USAGE="usage: symlink.sh <file>"
get_ctime() {
perl -se 'use File::stat; $file=lstat($filename); print $file->ctime' -- -filename="$1"
}
stat_inode() {
perl -se 'use File::stat; $file=stat($filename); if (defined $file) { print $file->ino; }' -- -filename="$1"
}
lstat_inode() {
perl -se 'use File::stat; $file=lstat($filename); if (defined $file) { print $file->ino; }' -- -filename="$1"
}
if [ $# -eq 0 ]; then
echo "$USAGE"
exit 1
fi
FILE_NAME="$1"
FILE_INODE=$(stat_inode "$FILE_NAME")
if [ ! -e "$FILE_NAME" ]; then
echo "no such file \"$FILE_NAME\""
exit 1
fi
for LINK in ./* ./.[!.]* ;do
if [ -L "$LINK" ]; then
TARGET_INODE=$(stat_inode "$LINK")
if [ ! -z "$TARGET_INODE" ]; then
if [ "$FILE_INODE" -eq "$TARGET_INODE" ]; then
echo $(get_ctime "$LINK") $(lstat_inode "$LINK");
fi
fi
fi
done | sort -nk1 | awk '{print $2}'
Basically, I'd like to pipe awk to some kind of lookup function like this: | awk ' ' | lookup
I'd really appreciate if someone suggested a more elegant way to accomplish the task.
OS: SunOS 5.10
Shell: KSH
Something like this?
$ find . -maxdepth 1 -inum 2883399
./.jshintrc
$
or:
$ echo 2883399 | xargs -IX find . -maxdepth 1 -inum X
./.jshintrc
$

How does ps aux | grep '[p]attern' exclude grep itself?

The title says it all. I've seen this idiom used alot instead of adding an additional grep -v grep in some ps pipeline. For example it could be used like this:
$ ps aux | grep '[f]irefox' | awk '{ print $8 }'
instead of
$ ps aux | grep 'firefox' | grep -v grep | awk '{ print $8 }'
It's super-convenient, but how does it work and why?
The pattern [f]irefox will not match the literal string [f]irefox. Instead it will match strings with exactly one char from the 1-character class [f], followed by irefox.

Perl telnet command not sending every command

I have the following program below which telnets into another device and prints serial number and Mac address.
My problem is that for some reason if I send the command once it skips the first command and sends the second, but if I copy the same command twice it will send the command.
What is the correct way to send a command multiple commands successively?
Should the buffer be flushed after every command sent ?
My Env
Eclipse Ide
Ubuntu 12.10
perl 5, version 14, subversion 2 (v5.14.2)
Snippet of my code:
$telnet = Net::Telnet->new($remoteSystem);
$| = 1;
$telnet->buffer_empty();
$telnet->buffer_empty();
$result = $telnet->input_log($errorlog);
#$_ = "#lines";
#TSN =$telnet->cmd('export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2');
#TSN =$telnet->cmd('export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2');
#mac = $telnet->cmd('ifconfig | grep eth0 | cut -d" " -f 11');
print "#TSN AND #TSN #mac";
print FH "$remoteSystem\n";
print "Telnetting into $remoteSystem .\n"; # Prints names of the tcd
close(telnet);
}
foreach (#host) {
checkStatus($_);
}
OUTPUT That skips the first command:
bash-2.02 AND bash-2.02 ifconfig | grep eth0 | cut -d" " -f 11
00:11:D9:3C:6E:02
bash-2.02 #
bash-2.02 Telnetting into debug79-109 .
OUTPUT That works but I have to send the same command twice:
export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2
AE20001901E2FD1
bash-2.02 #
bash-2.02 AND export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2
AE20001901E2FD1
bash-2.02 #
bash-2.02 ifconfig | grep eth0 | cut -d" " -f 11
00:11:D9:3C:6E:02
bash-2.02 #
bash-2.02 Telnetting into debug79-109
Specify the command prompt in your call to cmd(), e.g.#TSN =$telnet->cmd('export | grep -e SerialNumber..[A-Z] | cut -d"\"" -f2', Prompt => 'bash-2.02 #');
Try opening a connection after creating a object for the module telnet
$telnet->open($host);
After which execute waitFor method:(waits until the pattern bash-2.02 # comes)
$telnet->waitFor(/^(bash-\d+.\d+ #)$/);
and then execute your commands , it would give you proper output.

How do I find the largest 10 files in a given directory?

How do I find the largest 10 files in a given directory, with Perl or Bash?
EDIT:
I need this to be recursive.
I only want to see large files, no large directories.
I need this to work on Mac OS X 10.6 ('s version of find).
This prints the 10 largest files recursively from current directory.
find . -type f -printf "%s %p\n" | sort -nr | awk '{print $2}' | head -10
$ alias ducks
alias ducks='du -cs * |sort -rn |head -11'
This is a way to do it in perl. (Note: Non-recursive version, according to earlier version of the question)
perl -wE 'say for ((sort { -s $b <=> -s $a } </given/dir/*>)[0..9]);'
However, I'm sure there are better tools for the job.
ETA: Recursive version, using File::Find:
perl -MFile::Find -wE '
sub wanted { -f && push #files, $File::Find::name };
find(\&wanted, "/given/dir");
#files = sort { -s $b <=> -s $a } #files;
say for #files[0..9];'
To check file sizes, use e.g. printf("%-10s : %s\n", -s, $_) for #files[0..9]; instead.
How about this -
find . -type f -exec ls -l {} + | awk '{print $5,$NF}' | sort -nr | head -n 10
Test:
[jaypal:~/Temp] find . -type f -exec ls -l {} + | awk '{print $5,$NF}' | sort -nr | head -n 10
8887 ./backup/GTP/GTP_Parser.sh
8879 ./backup/Backup/GTP_Parser.sh
6791 ./backup/Delete_HIST_US.sh
6785 ./backup/Delete_NORM_US.sh
6725 ./backup/Delete_HIST_NET.sh
6711 ./backup/Delete_NORM_NET.sh
5339 ./backup/GTP/gtpparser.sh
5055 ./backup/GTP/gtpparser3.sh
4830 ./backup/GTP/gtpparser2.sh
3955 ./backup/GTP/temp1.file

while loop align columns

hi
I wrote a perl script where I stored columns from a text file filled with ip and port scans into variables. The variables contain many ip addreses, ports, protocols, states, and services now I need a while loop that takes all the ip's stored in the ip variable and matches them with its corresponding ports protocols and state etc.side by side look so:
192.168.3 45 tcp open smtp
heres my code
$ip_address = `cat /cygdrive/c/Windows/System32/test11.txt |
grep 'Nmap scan report for'`;
$state = `cat /cygdrive/c/Windows/System32/test11.txt | grep -v 'PORT'|
grep -v 'filtered'| grep -v 'latency'| grep -v 'Nmap' | grep -v 'Discovered' |
grep -v 'Raw' | grep -v 'SYN' | grep -v 'DNS'| grep -v 'Ping' |
grep -v 'Scanning' `;
$port = `cat /cygdrive/c/Windows/System32/test11.txt | grep -v 'Discovered'|
grep -v 'Nmap' | grep -v 'PORT' | grep -v 'ports'| grep -v 'Read' |
grep -v 'Raw'| grep -v 'Completed'| grep -v 'DNS' | grep -v 'hosts' |
grep -v 'Ping' | grep -v 'SYN' | grep -v 'latency' `;
$protocol = `cat /cygdrive/c/Windows/System32/test11.txt | grep -v 'Discovered'|
grep -v 'Nmap' | grep -v 'PORT' | grep -v 'ports'| grep -v 'Read' |
grep -v 'Raw' | grep -v 'Completed'| grep -v 'DNS' | grep -v 'hosts' |
grep -v 'Ping' | grep -v 'SYN' | grep -v 'latency' `;
{
$service = `cat /cygdrive/c/Windows/System32/test11.txt | grep -v 'Nmap' |
grep-v 'Host' | grep -v 'filtered' | grep -v 'PORT' | grep -v 'Raw'|
grep -v 'Scanning'| grep -v 'Completed'| grep -v 'Ping' |grep -v 'DNS' |
grep -v 'Discovered'| grep -v 'SYN'`;
while($ip_address, $port, $protocol, $state, #service)
{
chomp ($ip_address, $port, $protocol, $state, #service);
print "$ip_address, $port, $protocol, $state, #service";
exit 0;
}
Usually I say to use the tools that you understand and that it's OK to do things like call awk from Perl. But for this code I'll make an exception. You should be using the builtin Perl commands for this task. Namely, arrays and Perl's grep operator. Here's how I would start to rewrite this.
# do this once instead of `cat ...` several times.
open my $fh, '<', '/cygdrive/c/Windows/System32/test11.txt';
my #the_input = <$fh>;
close $fh;
# do this instead of `| grep -v ... | grep -v ...`
my #ip_addresses = grep { /Nmap scan report for/ } #the_input;
my #states = grep {
!/PORT|filtered|latency|Nmap|Discovered|Raw|SYN|DNS|Ping|Scanning/
} #the_input;
my #ports = grep {
!/Discovered|Nmap|PORT|ports|Read|Raw|Completed|DNS|hosts|Ping|SYN|latency/
} #the_input;
my #protocols = grep {
!/Discovered|Nmap|PORT|ports|Read|Raw|Completed|DNS|hosts|Ping|SYN|latency/
} #the_input;
my #services = grep {
!/Nmap|Host|filtered|PORT|Raw|Scanning|Completed|Ping|DNS|Discovered|SYN/
} #the_input;
I usually try to do these sorts of things in one pass, like...
#!/usr/bin/perl
open(F, "/cygdrive/c/Windows/System32/test11.txt");
while(<F>) {
# If the current line has something that matches an IP
# address, store the matched pattern in $ip. We'll
# use this as we process the remaining lines.
#
$ip = $1 if ( /Nmap scan report for (\d+\.\d+\.\d+\.\d+)/ );
# Try to match lines like "ddd/www www www wwww"
#
( $port, $protocol, $state, $service) = ( m|(\d+)/(\w+)\s+(\w+)\s+(\w+)| );
print "$ip, $port, $protocol, $state, $service\n" if $port;
}