trying to use while read loop to save result to an array - arrays

Quick question, can i do this?:
while IFS=: read menu script
do
echo "$x. $menu"
command[x]="$script"
let x++
done < file.txt
read two strings per line from a file, print one and save the other to an array..
file.txt looks like this:
File Operations:~/scripts/project/File_Operations.sh
Directory Operations:~/scripts/project/Directory_Operations.sh
Process Management:~/scripts/project/Process_Management.sh
Search Operations:~/scripts/project/Search_Operations.sh

Looks right. 2 things.
You need to initialise x. x=0
When you use x as a subscript it needs the $. i.e. command[$x]="$script"
And done forget the {}s when referencing the command array. e.g. ${command[0]}

What shell are you using? Works for me in bash, I just prepended the following two lines to the script:
#!/bin/bash
x=0
Without setting $x to 0, the user is presented with
. File Operations
1. Directory Operations
2. Process Management
3. Search Operations

Related

Run TreSpEx analysis

I am trying to run TreSpex analysis on a series of trees, which are saved in newick format as .fasta.txt files in a folder.
I have a list of Taxa names saved in a .txt file
I enter:
perl TreSpEx.v1.pl -fun e -ipt *fasta.txt -tf Taxa_List.txt
But it won't run. I tried writing a loop for each file within the folder but am not very good with them and my line of
for i in treefile/; do perl TreSpEx.v1.1.pl -fun e -ipt *.fasta.txt -tf Taxa_List.txt; done
won't work because -ipt apparently needs a name that starts with a letter or number
In your second example you are actually doing the same thing as in first (but posible several times).
I'm not familiar with TreSpEx or know Bash very well for that matter (which it seems you are using), but you might try something like below.
for i in treefile/*.fasta.txt ; do
perl TreSpEx.v1.1.pl -fun e -ipt $i -tf Taxa_List.txt;
done
Basically, you need to use a variable from the for loop (i) to pass name of each file to the command.

Passing an array as an argument from a Perl script to a R script

I am new to R and I have a Perl Script in which I want to call a R Script, which calculates something for me (not important what in this context). I want to give as arguments an input file, an array which contains some numbers and a number for a total number of clusters. medoid.r is the name of my R Script.
my $R_out;
$R_out = qx{./script/medoid.r $output #cluster $NUMBER_OF_CLUSTERS}
My current R code looks like this. Right now I just print cluster to see what is inside.
args <- commandArgs(TRUE)
filename = args[1]
cluster = as.vector(args[2])
number_of_cluster = args[3]
matrix = read.table(filename, sep='\t', header=TRUE, row.names=1, quote="")
print(cluster)
Is it possible to give an array as an argument? How can I save it in R? Right now only the first number of the array is stored and printed, but I would like to have every number in a vector or something similar.
If you do this in Perl
$R_out = qx{./script/medoid.r $output #cluster $NUMBER_OF_CLUSTERS};
your command line will look similar to this
./scriptmedoid.r output 111 222 333 3
assuming that $output is 'output' and #clusters = (111, 222, 333).
If you want to read that in R, you need to assign all elements after the first one in args to cluster but the last one, and the last one to number_of_cluster. In Perl you can use shift and pop for that.
my #args = #_;
my $output = shift #args;
my $number = pop #args;
# now #args only contains the clusters
I don't know if those operators exist in R.
You cannot pass a full data structure unless you serialize it in some way.
In perl, qx will expect a string as an argument. You may certainly use an array to generate that string, but ultimately it will still be a string. You cannot "pass an array" to a system call, you can only pass command-line text/arguments.
Keep in mind, you are executing a system call running Rscript as a child process. The way you're describing the issue, there is no inter-process communication beyond the command line. Think of it this way: how would you type an array on the command line? You may have some textual way of representing an array, but you can't type an array on the command line. Arrays are stored and accessed in memory differently by various different languages, and thus are not really portable between two languages like you're suggesting.
One solution: all that said, there may be a simple solution for you. You haven't provided any information on the type of data you want to pass in your array. If it is simple enough, you may try passing it on the command line as delimited text, and then break it up to use in your Rscript.
Here is an Rscript that shows you what I mean:
args = commandArgs(trailingOnly=TRUE)
filename = args[1]
cluster <- c(strsplit(args[2],"~"))
sprintf("Filename: %s",filename)
sprintf("Cluster list: %s",cluster)
print("Cluster:")
cluster
sprintf("First Item: %s",cluster[[1]][1])
Save it as "test.r" and try executing it with "Rscript test.r test.txt one~two" and you'll get the following output (tested on Rscript 46084, OpenBSD):
[1] "Filename: test.txt"
[1] "Cluster list: c(\"one\", \"two\")"
[1] "Cluster:"
[[1]]
[1] "one" "two"
[1] "First Item: one"
So, all you'd have to do on the perl side of things is join() your array using "~" or any other delimiter- it is highly dependent on your data, and you haven't provided it.
Summary: re-think how you want to communicate between perl and Rscript. Consider sending the data as a delimited string (if it's the right size) and breaking it up on the other side. Look into IPC if that won't work, consider environment variables or other options. There is no way to send an array reference on the command-line.
Note: you may want to read up on security risks of different system calls in perl.

Can't fill bash array

I'm running Ubuntu 14.04 and am trying to fill an array in a shell script so that I can loop over it and utilize its contents to fill a text file. However, there's a snag: it doesn't seem to be filling.
I've simplified the larger script that I'm working with down to the essential issue, reprinted below:
WL_START=1
WL_END=5
WL_INC=1
wl_range=$(seq $WL_START $WL_INC $WL_END)
declare -a WL
for i in $wl_range # loop through sequence and fill array
do
WL[$i]=${wl_range[$i]}
done
echo $wl_range
echo ${wl_range[1]}
echo $WL
echo ${WL[1]}
However, my output looks like this:
1 2 3 4 5
empty line
empty line
empty line
Any ideas? I know that people say to just use seq to fill the array, but I had the same problem there as well.
Too much work.
WL=($(seq $WL_START $WL_INC $WL_END))
wl_range is a string consisting of space-delimited numbers, not an array. Your for loop should simply look like
for i in $wl_range; do
WL[i]=$i
done
That said, don't use the for loop; use #IgnacioVazquez-Abrams' answer.

return to position in array after exit

Apparently I wasn't clear when I last asked this, I'll try again.
I have an array full of values, lets call them primenumbers.txt
I have a bash script lets call it primechecker
The script will take each and every value and in the array and 1 at a time and run it through. However I want to be able to stop primechecker at some point in processing this array; lets call it X and restart the script in a way that the start position in the array is X+1.
If there is some further clarification need please let me know.
Could you store the current index in a file in /tmp and check for that file on startup:
for i in nums; do
echo $i > /tmp/marker
...
done
You can try to make a global env variable and store possition in it.
For Example:
add this "export ARRAY_POS=""" to ./.profile
relogin and then
update you script like this:
#!/usr/bin/env bash
for i in nums; do
ARRAY_POS="$i"
...
done

Executing nested loops+foreach+csh

It's been a while since I used csh formatting and I am having a little bit of trouble with a few things. Things seem so much easier to execute in Matlab, however I need to do this on the terminal because of the programs I am trying to interact with.
So here's what I want to do: I have a file del.txt that is structured like this
1
2
3
4
etc. So each value is in it's own row and there's one column for all the data. I have a bunch of other files that are within my directory. I want to match up say value 1 (which in this case is 1) with file 1 and value 2 with file 2, etc and so on and so forth. So here's what I did...
Code:
!/bin/csh
foreach a (cat del.txt)
foreach sta(ls *.HHZ)
echo a is $a
echo $sta
cat <<END>>macro.m
r $a
r $sta
END
sac macro.m
rm macro.m
end
end
However what I achieve is that it loops through all of the values in del.txt and each file and then moves on to the next file within my directory and loops through all of the values. I'm having trouble figuring out the format that this should be in to match up the correct values. I'm not doing much within the script yet until I can get them to match up. Please help Can someone tell me what I'm doing wrong? I read that the foreach command will execute all the commands on each file..but haven't been able to find a way to get around this. What I want it to do is take value 1 from del.txt and match it up with file 1 (sta) from the directory finish the loop, then take value 2 from del.txt and match it up with file 2 from the directory (sta). I've never done more than just simple iterations with csh on one subset of files, and I am not sure how to reference the values to one another. Any help would be greatly appreciated. I haven't found a simple way to do this without writing everything out. I looked at the 'for' and 'while' commands..if there is a simple way to do it I'm not seeing it.
Cheers,
K
IF I am understanding correctly, You have a txt file will list of strings and you want it to match with the files.
I am assuming by this particular statement of yours:
I want to match up say value 1 (which in this case is 1) with file 1
You mean to match the string at 1 with file name of file 1.
Here's a possible solution based on this assumption(this will help you anyway with loop):
#Store value in file.txt in a array
set file_var = `cat file.txt`
#Store file list in my_dir in a var
set my_dir = <your dir path>
set file_list_var = `ls $my_dir`
#Let's print "file Match: for every match
foreach var1 ($file_var)
foreach var2 ($file_list_var)
if("$var1" == "$var2") echo $var1 = $var2 : Match Found.
endif
endif

Resources