Looping an array index into a screen session [duplicate] - arrays

This question already has answers here:
Bash array as argument inside of screen
(2 answers)
Closed 8 years ago.
#!/bin/bash
IFS=$'\n'
fortune_lines=($(fortune | fold -w 30))
Screen_Session=$"{mainscreen}"
Screen_OneLiner=$(screen -p 0 -S ${Screen_Session} -X stuff "`printf "say ${fortune_lines[#]}\r"`")
for var in "${Screen_OneLiner[#]}"
do
echo -e "${var}"
done
The above script only prints out line 1 one of
IFS=$'\n'
fortune_lines=($(fortune | fold -w 30))
Instead of cycling through the whole index of "fortune_lines" Not sure how to make this work.
Any ideas?
FYI
I am only using
echo -e
to troubleshoot this script.

#!/bin/bash
#OLDIFS=$IFS
IFS=$'\r'
fortune_lines=($(cat /etc/passwd | fold -w 30))
#Screen_Session=$"{mainscreen}"
Screen_Session=`screen -ls|grep "\."|grep "("|awk '{print $1}'`
Screen_OneLiner=$(screen -p 0 -S ${Screen_Session} -X stuff "`printf "say ${fortune_lines[#]}\r"`")
#IFS=$OLDIFS;
for var in "${Screen_OneLiner[#]}"
do
echo -e "${var}"
done
works fine for me I changed IFS to \r and it pumped out /etc/passwd where as with \n it only printed 1st line

Related

Bash. Split text to array by delimiter [duplicate]

This question already has answers here:
How to split a string into an array in Bash?
(24 answers)
Closed 1 year ago.
Can somebody help me out. I want to split TEXT(variable with \n) into array in bash.
Ok, I have some text-variable:
variable='13423exa*lkco3nr*sw
kjenve*kejnv'
I want to split it in array.
If variable did not have new line in it, I will do it by:
IFS='*' read -a array <<< "$variable"
I assumed the third element should be:
echo "${array[2]}"
>sw
>kjenve
But with new line it is not working. Please give me right direction.
Use readarray.
$ variable='13423exa*lkco3nr*sw
kjenve*kejnv'
$ readarray -d '*' -t arr < <(printf "%s" "$variable")
$ declare -p arr
declare -a arr=([0]="13423exa" [1]="lkco3nr" [2]=$'sw\nkjenve' [3]="kejnv")
mapfile: -d: invavlid option
Update bash, then use readarray.
If not, replace separator with zero byte and read it element by element with read -d ''.
arr=()
while IFS= read -d '' -r e || [[ -n "$e" ]]; do
arr+=("$e")
done < <(printf "%s" "$variable" | tr '*' '\0');
declare -p arr
declare -a arr=([0]="13423exa" [1]="lkco3nr" [2]=$'sw\nkjenve' [3]="kejnv")
You can use the readarray command and use it like in the following example:
readarray -d ':' -t my_array <<< "a:b:c:d:"
for (( i = 0; i < ${#my_array[*]}; i++ )); do
echo "${my_array[i]}"
done
Where the -d parameter defines the delimiter and -t ask to remove last delimiter.
Use a ending character different than new line
end=.
read -a array -d "$end" <<< "$v$end"
Of course this solution suppose there is at least one charecter not used in your input variable.

How to read tab-delimited fields into an array [duplicate]

This question already has answers here:
Read tab-separated file line into array
(3 answers)
Closed 1 year ago.
I have file HOMO.txt with this content:
1506 -4.6242 2.00000
I am using below commands:
$ mapfile -t myArray < HOMO.txt
$ echo ${myArray[0]}
1506 -4.6242 2.00000
$ echo ${myArray[1]}
The last command is returning a blank line. What I want is, to assign the middle value to a variable. Can anybody please suggest a fix.
By default mapfile uses newline as element delimiter. You can change it to space " " with the -d option like follows.
mapfile -t -d " " myArray < HOMO.txt
echo ${myArray[0]}
echo ${myArray[1]}
# Output
1506
-4.6242

How do i echo specific rows and columns from csv's in a variable?

The below script:
#!/bin/bash
otscurrent="
AAA,33854,4528,38382,12
BBB,83917,12296,96213,13
CCC,20399,5396,25795,21
DDD,27198,4884,32082,15
EEE,2472,981,3453,28
FFF,3207,851,4058,21
GGG,30621,4595,35216,13
HHH,8450,1504,9954,15
III,4963,2157,7120,30
JJJ,51,59,110,54
KKK,87,123,210,59
LLL,573,144,717,20
MMM,617,1841,2458,75
NNN,234,76,310,25
OOO,12433,1908,14341,13
PPP,10627,1428,12055,12
QQQ,510,514,1024,50
RRR,1361,687,2048,34
SSS,1,24,25,96
TTT,0,5,5,100
UUU,294,1606,1900,85
"
IFS="," array1=(${otscurrent})
echo ${array1[4]}
Prints:
$ ./test.sh
12
BBB
I'm trying to get it to just print 12... And I am not even sure how to make it just print row 5 column 4
The variable is an output of a sqlquery that has been parsed with several sed commands to change the formatting to csv.
otscurrent="$(sqlplus64 user/password#dbserverip/db as sysdba #query.sql |
sed '1,11d; /^-/d; s/[[:space:]]\{1,\}/,/g; $d' |
sed '$d'|sed '$d'|sed '$d' | sed '$d' |
sed 's/Used,MB/Used MB/g' |
sed 's/Free,MB/Free MB/g' |
sed 's/Total,MB/Total MB/g' |
sed 's/Pct.,Free/Pct. Free/g' |
sed '1b;/^Name/d' |
sed '/^$/d'
)"
Ultimately I would like to be able to call on a row and column and run statements on the values.
Initially i was piping that into :
awk -F "," 'NR>1{ if($5 < 10) { printf "%-30s%-10s%-10s%-10s%-10s\n", $1,$2,$3,$4,$5"%"; } else { echo "Nothing to do" } }')"
Which works but I couldn't run commands from if else ... or atleaste I didn't know how.
If you have bash 4.0 or newer, an associative array is an appropriate way to store data in this kind of form.
otscurrent=${otscurrent#$'\n'} # strip leading newline present in your sample data
declare -A data=( )
row=0
while IFS=, read -r -a line; do
for idx in "${!line[#]}"; do
data["$row,$idx"]=${line[$idx]}
done
(( row += 1 ))
done <<<"$otscurrent"
This lets you access each individual item:
echo "${data[0,0]}" # first field of first line
echo "${data[9,0]}" # first field of tenth line
echo "${data[9,1]}" # second field of tenth line
"I'm trying to get it to just print 12..."
The issue is that IFS="," splits on commas and there is no comma between 12 and BBB. If you want those to be separate elements, add a newline to IFS. Thus, replace:
IFS="," array1=(${otscurrent})
With:
IFS=$',\n' array1=(${otscurrent})
Output:
$ bash test.sh
12
All you need to print the value of the 4th column on the 5th row is:
$ awk -F, 'NR==5{print $4}' <<< "$otscurrent"
3453
and just remember that in awk row (record) and column (field) numbers start at 1, not 0. Some more examples:
$ awk -F, 'NR==1{print $5}' <<< "$otscurrent"
12
$ awk -F, 'NR==2{print $1}' <<< "$otscurrent"
BBB
$ awk -F, '$5 > 50' <<< "$otscurrent"
JJJ,51,59,110,54
KKK,87,123,210,59
MMM,617,1841,2458,75
SSS,1,24,25,96
TTT,0,5,5,100
UUU,294,1606,1900,85
If you'd like to avoid all of the complexity and simply parse your SQL output to produce what you want without 20 sed commands in between, post a new question showing the raw sqlplus output as the input and what you want finally output and someone will post a brief, clear, simple, efficient awk script to do it all at one time, or maybe 2 commands if you still want an intermediate CSV for some reason.

Bash - Compare User input with array [duplicate]

This question already has answers here:
Array intersection in Bash [duplicate]
(5 answers)
Closed 6 years ago.
I want to validate did user input proper device in whiptail dialog or did user input something wrong.
I'm googling this for 2 days and can'f find any similar question/issue.
This is my code:
ALL_DEVICES=$(ifconfig -a | grep Ethernet | awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
U_INPUT=$(whiptail --title "[choose]" --inputbox "Please input your device" 0 0 all 3>&1 1>&2 2>&3)
If I do echo "$ALL_DEVICES" I'll get: eth0 wlan0
Let's assume that user input: eth wlan0 wlan1
How can I inform user that he input correctly: wlan0 , BUT eth and wlan1 is incorrect input, since that devices doesn't exist.
I tried this code:
ALL_DEVICES=$(ifconfig -a | grep Ethernet | awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
U_INPUT=$(whiptail --title "[choose]" --inputbox "Please input your device" 0 0 3>&1 1>&2 2>&3)
arr1=("$ALL_DEVICES")
arr2=("$U_INPUT")
echo "arr1 ${arr1[#]}"
echo "arr2 ${arr2[#]}"
FOUND="echo ${arr1[*]} | grep ${arr2[*]}"
if [ "${FOUND}" != "" ]; then
echo "Valid interfaces: ${arr2[*]}"
else
echo "Invalid interfaces: ${arr2[*]}"
fi
Thank you very much
I would go like this:
devices="eth0 wlan0"
input="eth0 whlan0 wlan0"
#translate output strings to array based on space
IFS=' ' read -r -a devicesa <<< "$devices"
IFS=' ' read -r -a inputa <<< "$input"
for i in "${inputa[#]}"
do
for j in "${devicesa[#]}"; do
if [ ${i} == ${j} ]; then
correct=1
break
else
correct=0
fi
done
if [ $correct = 1 ]; then
echo "device $i is correct"
else
echo "device $i isnt correct"
fi
done
Maybe it could be more simplified, but you can read the steps to do. First go through array of strings, find devices, than compare them with user imput with writing walue about finding it. Last step is to clarify whether the value was found or not.

Adding a string to the front of array loop?

#!/bin/bash
#OLDIFS=$IFS
IFS=$'\r'
fortune_lines=($(fortune | fold -w 90))
#Screen_Session=$"{mainscreen}"
Screen_Session=`screen -ls|grep "\."|grep "("|awk '{print $1}'`
Screen_OneLiner=$(screen -p 0 -S ${Screen_Session} -X stuff "`printf "${fortune_lines[#]}\r"`")
#IFS=$OLDIFS;
for var in "${Screen_OneLiner[#]}"
do
echo "${var}"
done
ok this script works (sorta). I need to at the string "say " to front of the entire array index. Currently I can only get it to print out "say " to the first line.
We need not complicate things with contraptions like arrays - we can let good old sed do the job.
#!/bin/bash
fortune_lines=$(fortune | fold -w 90 | sed 's/^/say /')
Screen_Session=`screen -ls|grep "\."|grep "("|awk '{print $1}'`
screen -p 0 -S $Screen_Session -X stuff "$fortune_lines"

Resources