Finding numbers in file (script, bash) - linux

I want to find number or words in file. As first parameter it gets file name and second number you are looking for.
For example I write in command line:
bash script.sh file.txt 6
And i get on output
Number 6 repeats 4 time
This is content in file.txt
5 4 5 6 2 4 6 3 6 6
This is the code what I came up and stuck
para2=$2
while read line
do
array=($line)
echo "Value of third element in my array : ${array[3]} "
done < $1
I dont know how to compare parameter 2 with every array. I know that in code above I print out third array but I dont know how to go through every array and compare them with parameter two. I mean i want to go through all numbers and compare with input parameter. Pleas help

Try this:
numOccurences=0
while read line
do
array=($line)
for i in "${array[#]}"
do
if [ "$2" = "$i" ]
then
numOccurences=`expr $numOccurences + 1`
fi
done
done < $1
echo "$2 occurs $numOccurences times in $1"
The program will read a line, iterate through the array formed by the line, and then it will compare the value to the target character. A counter is updated for every match, and the result is printed at the end.
Example input (file.txt):
5 4 5 6 2 4 6 3 6 6 6 6
6 6
᠎
Command:
/Users/Robert/Desktop/Untitled.sh /Users/Robert/Desktop/file.txt 6
Output:
6 occurs 8 times in /Users/Robert/Desktop/file.txt

para2=$2
counter=0
while read line
do
for num in $line
do
if [[ $num -eq $para2 ]]
then let counter = ((counter + 1))
fi
done
done < "$1"
echo Number $para2 repeats $counter times

#!/bin/bash
echo "Number to be searched $2 "
echo "File name passed : $1"
filename=$1
count=0
while read line
do
for word in $line; do
#echo "Number = $word"
if [ "$2" == "$word" ]; then
count=$(expr $count + 1)
fi
done
done < $filename
echo $2 is observed $count times

Related

How do I split a string on a pattern at the linux bash prompt and return the last instance of my pattern and everything after

This is my first question on StackOverflow, I hope it's not too noob for this forum. Thanks for your help in advance!!!
[PROBLEM]
I have a Linux bash variable in my bash script with the below content:
[split]
this is a test 1
[split]
this is a test 2
[split]
this is a test 3
this is a test 4
this is a test 5
How can I split this file on the string "[split]" and return the last section after the split?
this is a test 3
this is a test 4
this is a test 5
The last section can vary in length but it is always at the end of the "string" / "file"
Using awk, set record separator to the regular expression representing the split string, print the last record at END.
gawk 'BEGIN{ RS="[[]split[]]" } END{ print $0 }' tmp/test.txt
Result assuming input coming from a file:
this is a test 3
this is a test 4
this is a test 5
How about this ? :)
FILE="test.txt"
NEW_FILE="test_result.txt"
SPLIT="split"
while read line
do
if [[ $line == $SPLIT ]]
then
$(rm ${NEW_FILE})
else
$(echo -e "${line}" >> ${NEW_FILE})
fi
done < $FILE
#!/bin/bash
s="[split]
this is a test 1
[split]
this is a test 2
[split]
this is a test 3
this is a test 4
this is a test 5"
a=()
i=0
while read -r line
do
a[i]="${a[i]}${line}"$'\n'
if [ "$line" == "[split]" ]
then
let ++i
fi
done <<< "$s"
echo ${a[-1]}
I simply read each line from the string into an array and when I encounter [split] ,I increment the array index.At last,I echo the last element.
EDIT:
if you just want the last part no need for an array too.You could do something like
while read -r line
do
a+="${line}"$'\n'
if [ "$line" == "[split]" ]
then
a=""
fi
done <<< "$s"
echo $a

How to search string references in specified location?

I'm trying to find the occurence of elements list(from a text file) in a directory.
Below is the Bash code I'm using ,but I'm unable to get the output of grep command on to console.
!/bin/bash
FILENAME=$1
count=0
while read LINE
do
let count++
echo "$count $LINE"
grep -r $LINE /home/user/vaishnavi
done < $FILENAME
echo -e "\nTotal $count Lines read"
Output:
1 ASK
2 TELL
3 ORDER
4 NUMBER
5 SIZE
6 BASKET
7 FRUIT
8 VEGGIES
Total 8 Lines read
I'm getting only the list of elements but not their occurences in the specified location.
Is there anything wrong with my code?
Thanks.
You need to echo the result of the grep, for example:
echo $(grep -r $LINE /home/user/vaishnavi)

how to generate sequence of ones and zeros in bash script

I am trying to generate a sequence of ones and zeros in using bash script.
#!/bin/bash
clock=1
n=1
# continue until $n equals 5
while [ $n -le 5 ]
do
echo "$clock"
n=$(( n+1 )) # increments $n
clock=$(~clock)
done
Expected output:
1
0
1
0
1
Output generated from the above code:
I am getting error from this line: clock=$(~clock)
Error: ~clock: command not found
If you want to generate sequence with 1 and 0 alternatively, you can use
#!/bin/bash
clock=1
n=1
# continue until $n equals 5
while [ $n -le 5 ]
do
echo "$clock"
n=$(( n+1 ))
# increments $n
clock=$((clock+1))
clock=$((clock%2))
done
If you want to generate random sequence of 1 and 0s, you can use
#!/bin/bash
n=1
# continue until $n equals 5
while [ $n -le 5 ]
do
echo "$((RANDOM%2))"
n=$(( n+1 ))
done
Problem is in this line:
clock=$(~clock)
Here bash is trying to run anything inside $(...) as a command (it is called command substitution).
Using ~clock is also incorrect as it will only do bitwise negation and will not produce 1 and 0 as you are expecting.
You can use this script to get alternate 1 and 0 printed:
#!/bin/bash
clock=1
# continue until $n equals 5
for ((n=0; n<5; n++))
do
echo "$clock"
clock=$((1 - clock))
done
Another short way to do it
#!/bin/bash
for i in {1..5}
do
echo $((i%2))
done
Or slightly less concise but easier to configure with variables to define the loop :
#!/bin/bash
for ((i=1;i<=5;i++))
do
echo $((i%2))
done
Another one, just for fun (would not do that in a read script, more like a little puzzle to figure out why it works). Remove the "false" line to begin with 0.
#!/bin/bash
false
for i in {1..5}
do
echo $? ; [[ $_ != 0 ]]
done
You can utilize the following trick using the brace expansion.
echo {,,,,}{1,0}
This one will generate 5 pairs of ones and zeroes.

Bash expr error

I have a few text files with numbers (structure as below). I'd like to sum up every line form one file with ever line form other files (line1 from file1 + line1 from file2 etc.). I have written the bash script as following but this gives me the expr error.
function countHourly () {
for i in {1..24}
do
for file in $PLACE/*.dailycount.txt
do
SECBUFF=`head -n $i $file`
VAL=`expr $VAL + $SECBUFF` ## <-- this cause expr error
done
echo line $i form all files counts: $VAL
done
}
file structure *.dailycount.txt:
1
0
14
56
45
0
3
45
23
23
9 (every number in new line).
Assuming your files each contain exactly 24 lines, you could solve this problem with a simple one-liner:
counthourly() {
paste -d+ $PLACE/*.dailycount.txt | bc
}
The head -n NUMBER FILE command outputs the first NUMBER lines. This means that SECBUFF ends up being 1 0 on the second run of the loop, and something like expr 1 + 2 3 is not a valid expression so you get an error from expr.
You can use sed to pick only the nth line from a file, but I wonder if you shouldn't restructure the program somehow.
SECBUFF=`sed -ne ${i}p $file`
This could help. With that variation you could check very input so that only numbers would be added for the sum, even if there are lines that invalid.
function countHourly {
local NUMBERS TOTAL=0 I
readarray -t NUMBERS < <(cat "$PLACE"/*.dailycount.txt)
for I in "${NUMBERS[#]}"; do
[[ $I =~ ^[[:digit:]]+$ ]] && (( TOTAL += I ))
done
echo "Total: $TOTAL"
}
Or
function countHourly {
local NUMBERS TOTAL=0 I
while read I; do
[[ $I =~ ^[[:digit:]]+$ ]] && (( TOTAL += I ))
done < <(cat "$PLACE"/*.dailycount.txt)
echo "Total: $TOTAL"
}

grabbing all arguments after nth argument and concatenating them together in bash

So I have a bash script that needs to take an arbitrary number of command line arguments and put them into a single string
Example of what the user would type in:
give <environment> <email> <any number of integers separated by spaces>
give testing stuff#things.com 1 2 3 4 5
I want to get all of the arguments from $3 to $# and concat them into a string.
My (probably awful) solution right now is
if [ $# -gt 3 ]
then
env="env="$1
email="email="$2
entList=""
for i in {3..$#}
do
if [ $i -eq 3 ]
then
entList=$3
shift
fi;
if [ $i -gt 3 ]
then
entList=$entList","$3
shift
fi;
done
fi;
I handle the case of having only three arguments a bit differently, and that one works fine.
Final value of $entList given the example give testing stuff#things.com 1 2 3 4 5 should be: 1,2,3,4,5
Right now when i run this i get the following Errors:
/usr/local/bin/ngive.sh: line 29: [: {3..5}: integer expression expected
/usr/local/bin/ngive.sh: line 34: [: {3..5}: integer expression expected
Lines 29 and 34 are:
line 29: if [ $i -eq 3 ]
line 34: if [ $i -gt 3 ]
Any help would be appreciated.
You're on the right track. Here's my suggestion:
if [ $# -ge 3 ]; then
env="$1"
email="$2"
entlist="$3"
while shift && [ -n "$3" ]; do
entlist="${entlist},$3"
done
echo "entlist=$entlist"
else
echo "Arguments: $*"
fi
Note that variables should always be put inside quotes. I'm not sure why you were setting env=env=$1, but I suspect that if you want to recycle that value later, you should do it programatically rather than by evaluating the variable as if it were a statement, in case that was your plan.
Skip first three arguments using a subarray:
all=( ${#} )
IFS=','
threeplus="${all[*]:3}"
The reason you're getting those error messages is that in:
for i in {3..$#}
The brace expansion is performed before the parameter expansion and so the following if statement is evaluated as:
if [ {3..$#} -eq 3 ]
which isn't valid.
Change your for statement to use the C style:
for ((i = 3; i <= $#; i++))
Use this style for integer comparison:
if (( $# > 3 ))
and
if (( i == 3 ))
and
if (( i > 3 ))
Put your parameters inside the quotes:
env="env=$1"
email="email=$2"
and
entList="$entList,$3"
although the quotes aren't necessary since word splitting isn't performed on the right side of an assignment and you're not assigning special characters such as whitespace, semicolons, pipes, etc.

Resources