Can't fill bash array - arrays

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.

Related

How to output specific cells of an array in bash?

Say I've got the following array:
items[0]=0
items[1]=1
items[2]=2
etc.
Using echo/printf, how would I output only specific cells, for instance only cells 0,2,4.
So far I've got this:
echo "${items[*]}"
This outputs all of the array, but how would I alter this line to make it only output the specified cells? I'm pretty sure I'm just missing what the syntax for this is.
Edit: Sorry, I inaccurately described what I'm asking. What I need to find out, is how to output the specified data point by calling the array only once.
For instance:
echo ${items[magical code stuff here]magical code stuff here too maybe}"
Replace the * with 0 2 4:
echo "${items[0]} ${items[2]} ${items[4]}"

Using awk to parse a string from a file

I'm still learning Unix and I'm having issues understanding the following line of code.
echo "$lines" | awk '{split($0,a,":"); print a[3],a[2],a[1]}'
I don't understand what is happening with the array a in the line of code above. Is it declaring the array and setting it equal to the string it's parsing? If it is declaring the array a, then, why can't I print out the results later on in the code?
echo "${a[1]}"
The line above prints an empty line and not what has been stored in the array a when the string was parsed. I know there is always something in the string that needs to be parsed and when I call the array a[1] I know that I'm in inside the scope. I just don't see/understand what is happening with the array a that prevents me from printing it out later on in the code.
Your code is printing a line for each line of input. If you dont have get output, my first guess would be, that you don't have input.
Given an input of:
lines="ab:cd:ef
ij:kl:m"
the output is:
ef cd ab
m kl ij
awk is executing the commands (which is everything in between the single quotes) for each line of input. First splitting the input line $0 at each : into an array a, then printing the first three elements in reverse order.
If you try to access an array element in the shell, what echo suggests, then you are too late. The array exists within awk and is gone when awk has finished.

Trouble storing the output of mediainfo video times into an array

For the life of me, I cannot figure out why I can't store the output of the mediainfo --Inform command into an array. I've done for loops in Bash before without issue, perhaps I'm missing something really obvious here. Or, perhaps I'm going about it the completely wrong way.
#!/bin/bash
for file in /mnt/sda1/*.mp4
do vidtime=($(mediainfo --Inform="Video;%Duration%" $file))
done
echo ${vidtime[#]}
The output is always the time of the last file processed in the loop and the rest of the elements of the array are null.
I'm working on a script to endlessly play videos on a Raspberry Pi, but I'm finding that omxplayer isn't always exiting at the end of a video, it's really hard to reproduce so I've given up on troubleshooting the root cause. I'm trying to build some logic to kill off any omxplayer processes that are running longer than they should be.
Give this a shot. Note the += operator. You might also want to add quotes around $file if your filenames contain spaces:
#!/bin/bash
for file in /mnt/sda1/*.mp4
do vidtime+=($(mediainfo --Inform="Video;%Duration%" "$file"))
done
echo ${vidtime[#]}
It's more efficient to do it this way:
read -ra vidtime < <(exec mediainfo --Inform='Video;%Duration% ' -- /mnt/sda1/*.mp4)
No need to use a for loop and repeatingly call mediainfo.

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

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

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