input from file $2 : 1 -> 2
while read -a line; do
if (( ${line[2]} > linesNumber )); then
echo "Graph does not match known sites4"
exit
fi
done < "$2"
For some reason inside the if condition, the value of ${line[2]) is not 2
but if I print the value outside if:
echo `${line[2]}`
2
What's linesNumber? Even if you put $linesNumber, where is it coming from?
If you are tracking the line number, you need to set it and increment it. Here's my sample program and data. It's inspired by your example, but doesn't do exactly what you want. However, it shows you how to setup a variable that tracks the line number, how to increment it, and how to use it in an if statement:
foo.txt:
this 1
that 2
foo 4
barf 4
flux 5
The Program:
lineNum=0
while read -a line
do
((lineNum++))
if (( ${line[1]} > $lineNum ))
then
echo "Line Number Too High!"
fi
echo "Verb = ${line[0]} Number = ${line[1]}"
done < foo.txt
Output:
Verb = this Number = 1
Verb = that Number = 2
Line Number Too High!
Verb = foo Number = 4
Verb = barf Number = 4
Verb = flux Number = 5
Related
I have a long string file (string.txt) (abcdefghijklmnop)
and a vcf table (file.vcf) which lools like that
position 2 4 6 10 n...
name1 a b c d
name2 x y z a
namen...
the table also contain "mis" and "het" and in this case the character should not be replaced
I want to change the characters in the specific location and store all the strings in a new file that will look like this
>name1
aacbecghidklmnop
>name2
axcyezghiaklmnop
is there a way to do it in a bash loop ?
Would you please try the following:
mapfile -t string < <(fold -w1 "string.txt")
# set string to an array of single characters: ("a" "b" "c" "d" ..)
while read -ra ary; do
if [[ ${ary[0]} = "position" ]]; then
# 1st line of file.vcf
declare -a pos=("${ary[#]:1}")
# now the array pos holds: (2 4 6 10 ..)
else
# 2nd line of file.vcf and after
declare -a new=("${string[#]}")
# make a copy of string to modify
for ((i=0; i<${#pos[#]}; i++ )); do
repl="${ary[$i+1]}" # replacement
if [[ $repl != "mis" && $repl != "het" ]]; then
new[${pos[$i]}-1]="$repl"
# modify the position with the replacement
fi
done
echo ">${ary[0]}"
(IFS=""; echo "${new[*]}")
# print the modified array as a concatenated string
fi
done < "file.vcf"
string.txt:
abcdefghijklmnop
file.vcf:
position 2 4 6 10
name1 a b c d
name2 x y z a
name3 i mis k l
Output:
>name1
aacbecghidklmnop
>name2
axcyezghiaklmnop
>name3
aicdekghilklmnop
I have tried to embed explanations as comments in the script above, but
if you still have a question, please feel free to ask.
Hope this helps.
#!/bin/bash
arrck=
arrrlt=
if true; then
arrck+=("1")
arrrlt+=("one")
else
echo "something"
fi
for i in ${!arrck[*]}
do
echo "${arrck[i]} is ${arrrlt[i]}"
done
output 1--
is
1 is one
output 2--tracing on
./Building_block.sh
+ arrck=
+ arrrlt=
+ true
+ arrck+=("1")
+ arrrlt+=("one")
+ for i in '${!arrck[*]}'
+ echo ' is '
is
+ for i in '${!arrck[*]}'
+ echo '1 is one'
1 is one
Why is the loop running with no value assigned to i ? i can say it tried to execute echo "${arrck[]} is ${arrrlt[]}" and picking the blank space as value.
When you assign a value to a variable you are actually assigning a value to cell/position 0 in an array, eg:
$ x=5
$ echo ${x}
5
$ echo ${!x[#]}
0
$ echo ${x[0]}
5
$ echo ${x[#]}
5
In your example the first set of commands assign the empty string to index position '0' of the 2 arrays arrck[] and arrrlt[]:
$ arrck=
$ arrrlt=
$ echo "${!arrck[#]} : ${!arrrlt[#]}"
0 : 0
The if/then/else block then appends a second set of values to your arrays with indexes 1 and values of 1 and one.
The for loop then loops through the 2 available indices for the arrck[] array, namely 0 and 1.
What you probably want to do is start out by dropping/deallocating your arrays (as opposed to creating cell 0), eg:
$ unset arrck
$ unset arrrlt
$ echo "${!arrck[#]:-undefined} : ${!arrrlt[#]:-undefined}"
undefined : undefined
This is my simple shell script
root#Ubuntu:/tmp# cat -n script.sh
1 echo
2 while x= read -n 1 char
3 do
4 echo -e "Original value = $char"
5 echo -e "Plus one = `expr $char + 1`\n"
6 done < number.txt
7 echo
root#Ubuntu:/tmp#
And this is the content of number.txt
root#Ubuntu:/tmp# cat number.txt
12345
root#Ubuntu:/tmp#
As you can see on the code, I'm trying to read each number and process it separately. In this case, I would like to add one to each of them and print it on a new line.
root#Ubuntu:/tmp# ./script.sh
Original value = 1
Plus one = 2
Original value = 2
Plus one = 3
Original value = 3
Plus one = 4
Original value = 4
Plus one = 5
Original value = 5
Plus one = 6
Original value =
Plus one = 1
root#Ubuntu:/tmp#
Everything looks fine except for the last line. I've only have 5 numbers, however it seems like the code is processing additional one.
Original value =
Plus one = 1
Question is how does this happen and how to fix it?
It seems the input file number.txt contains a complete line, which is terminated by a line feed character (LF). (You can verify the input file is longer than 5 using ls -l.) read eventually encounters the LF and gives you an empty char (stripping the terminating LF from the input as it would without the -n option). This will give you expr + 1 resulting in 1. You can explicitely test for the empty char and terminate the while loop using the test -n for non-zero length strings:
echo "12345" | while read -n 1 char && [ -n "$char" ]; do echo "$char" ; done
I'm trying to write a bash script that calculates the average of numbers by rows and columns. An example of a text file that I'm reading in is:
1 2 3 4 5
4 6 7 8 0
There is an unknown number of rows and unknown number of columns. Currently, I'm just trying to sum each row with a while loop. The desired output is:
1 2 3 4 5 Sum = 15
4 6 7 8 0 Sum = 25
And so on and so forth with each row. Currently this is the code I have:
while read i
do
echo "num: $i"
(( sum=$sum+$i ))
echo "sum: $sum"
done < $2
To call the program it's stats -r test_file. "-r" indicates rows--I haven't started columns quite yet. My current code actually just takes the first number of each column and adds them together and then the rest of the numbers error out as a syntax error. It says the error comes from like 16, which is the (( sum=$sum+$i )) line but I honestly can't figure out what the problem is. I should tell you I'm extremely new to bash scripting and I have googled and searched high and low for the answer for this and can't find it. Any help is greatly appreciated.
You are reading the file line by line, and summing line is not an arithmetic operation. Try this:
while read i
do
sum=0
for num in $i
do
sum=$(($sum + $num))
done
echo "$i Sum: $sum"
done < $2
just split each number from every line using for loop. I hope this helps.
Another non bash way (con: OP asked for bash, pro: does not depend on bashisms, works with floats).
awk '{c=0;for(i=1;i<=NF;++i){c+=$i};print $0, "Sum:", c}'
Another way (not a pure bash):
while read line
do
sum=$(sed 's/[ ]\+/+/g' <<< "$line" | bc -q)
echo "$line Sum = $sum"
done < filename
Using the numsum -r util covers the row addition, but the output format needs a little glue, by inefficiently paste-ing a few utils:
paste "$2" \
<(yes "Sum =" | head -$(wc -l < "$2") ) \
<(numsum -r "$2")
Output:
1 2 3 4 5 Sum = 15
4 6 7 8 0 Sum = 25
Note -- to run the above line on a given file foo, first initialize $2 like so:
set -- "" foo
paste "$2" <(yes "Sum =" | head -$(wc -l < "$2") ) <(numsum -r "$2")
i'm trying to make script which will check if new deadlocks are created since last script run, if no new deadlock since last run it should print 0 if new deadlocks are created then it should print number
#DB profile
. /db2/tdb_inst/archinst/sqllib/db2profile;
#variable to get current deadlock count
a=`db2 get snapshot for all on archprd |grep Deadlock|head -1|awk '{print $4}'`
#variable to get last deadlock count
b=`cat /home/dbmon/script/darch`
#need your help to do below math in script
# if a$-b$ = 0 print 0 if a$-b$ > 0 print number
#after print export current deadlock count to darch file
echo $a > /home/dbmon/script/darch
TIA
tnt5273
need your help to do below math in script
if a$-b$ = 0 print 0 if a$-b$ > 0 print number
You can say:
(( a - b )) && echo $(( a - b )) || echo 0
This would print 0 if a = b else print a - b.
Actually, even the following should suffice:
echo $(( a - b ))