How to redirect grep to a while loop - bash

Hi I have the following bash script code
group2=0
while read -r line
do
popAll=$line | cut -d "{" -f2 | cut -d "}" -f1 | tr -cd "," | wc -c
if [[ $popAll = 0 ]]; then
group2 = $((group2+2));
else
group2 = $((group2+popAll+1));
fi
done << (grep -w "token" "$file")
and I get the following error:
./parsingTrace: line 153: syntax error near unexpected token `('
./parsingTrace: line 153: `done << (grep -w "pop" "$file")'
I do not want to pipe grep to the while, because I want variable inside the loop to be visible outside

The problem is in this line:
done << (grep -w "token" "$file")
# ^^
You need to say < and then <(). The first one is to indicate the input for the while loop and the second one for the process substitution:
done < <(grep -w "token" "$file")
# ^ ^
Note however that there are many others things you want to check. See the comments for a discussion and paste the code in ShellCheck for more details. Also, by indicating some sample input and desired output I am sure we can find a better way to do this.

Related

What's wrong with my function() in Shell Script! Syntax Token errors near {?

#!/bin/bash
# I get the newest file in Directory
latest_file=$(ls -t | head -n 1)
getAlldoublicate()
# getting Token syntax error here getAlldoublicate() '{
{
Alldoublicate=$(tr -s ',' ' ' <latest_file | awk '{print $2" "$3" "$4}' | uniq -d)
# here I try to find dublicate rows in csv
}
if [[ -s latest_file]] ; then
# here I check if file is emty
getAlldoublicate
else
cat "$latest_file" | mailx -s "$latest_file is empty" bla..`#bla
fi
I guess this is your code.
#!/bin/bash
# I get the newest file in Directory
latest_file=$(ls -t | head -n 1)
# getting Token syntax error here
getAlldoublicate()
{
# here I try to find dublicate rows in csv
Alldoublicate=$(tr -s ',' ' ' < $1 | awk '{print $2" "$3" "$4}' | uniq -d)
}
if [[ -s $latest_file ]]; then
# here I check if file is emty
getAlldoublicate $latest_file
else
cat $latest_file | mailx -s "$latest_file is empty" bla.. #bla
fi
Three points you need to pay attention:
function must be defined first before being use.
You can pass the latest_file as an argument when calling getAlldoublicate. Then you could use it by $1 in the function. ($0 stands for the function being called itself).
It would be better if you read the How to Format Tutorials before asking questions.

For loop and confition including Curl command

I am trying to write a script where I enumerate users by checking the HTTP reponse length. I want to get output "good" when response is not equal 23, however I get these errors now:
for ((i=113;i<=115;i++)); do
if [[curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" |
grep Content-Length | cut -d' ' -f2 != 23]]
then
echo "good"
fi
done
Output:
bash: [[curl: command not found
cut: !=: No such file or directory
cut: 23]]: No such file or directory
cut: !=: No such file or directory
cut: 23]]: No such file or directory
bash: [[curl: command not found
cut: !=: No such file or directory
cut: 23]]: No such file or directory
bash: [[curl: command not found
If I simply make a script without if condition, then it works well:
for ((i=113;i<=115;i++)); do
curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" |
grep Content-Length
done
I checked many examples but can't seem to figure out where I am doing wrong.
After updating your initial error, you may have a syntax like (suggestion: put some effort on format, so that it is more clear what you have and what may be wrong):
for ((i=113;i<=115;i++))
do
if [[ curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2 != 23 ]]
then
echo "good"
fi
done
This is returning you the error:
bash: conditional binary operator expected bash: syntax error near
-i'`
Which is normal, because you are basically saying:
if [[ command ]]; then ...
Where command is a set of multiple piped commands. However, in [[ you just can add expressions on the form "$var" -eq 23 or "$(command)" -ne 23.
So use $( ) to execute the command: if [[ "$(command)" -ne 23 ]]:
if [[ "$(curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2)" -ne 23 ]]
Note I am using -ne to perform an integer comparison that means "not equal to".
Finally, notice that awk alone can do what grep and cut do in two steps:
... | grep "Content-Length" | cut -d' ' -f2
This means: check the line containing "Content-Length" and print its second field. awk makes it simple by saying:
... | awk '/Content-Length/ {print $2}'
And last, but not least, your expression for ((i=113;i<=115;i++)) can be also written as for i in {113..115} using brace expansion.
If you want to test a result of the command execution you should put it into $() . So the resulting script should look as follows:
for i in {113..115}; do if [[ $(curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2) != 23 ]]; then echo "good" ; fi; done
Also I've changed a way you iterate the values. {a..b} in bash provides a sequence from 'a' to 'b'.

Errors in bash script. Syntax error near unexpected token

Do you know what is wrong with my script as I always get the error mesage:
position frac1 frac2
: command not found:
'/s1_met.sh: line 3: syntax error near unexpected token `do
'/s1_met.sh: line 3: `for lineF1 in $(cat $1); do
Code here:
export IFS=$'\n'
echo "position frac1 frac2";
for lineF1 in $(cat $1); do
if [ $(echo $lineF1 | cut -b 1-2) = "##" ]; then
echo "skip line" >&2;
else
startF1=$(echo $lineF1 | cut -f 4);
stopF1=$(echo $lineF1 | cut -f 5);
fracF1=$(echo $lineF1 | cut -f 9 | cut -d ";" -f 4 | cut -d "=" -f 2);
lineF2=$(grep "$startF1" $2);
if [ -z "$lineF2" ]; then
echo "position $startF1 cannot be found" >&2;
else
fracF2=$(echo $lineF2 | cut -f 9 | cut -d ";" -f 4 | cut -d "=" -f 2);
echo "$startF1 $fracF1 $fracF2";
fi;
fi
done;
There's nothing wrong with it, you must not be running it with BASH.
Edited to say you need to check your line endings, your comment below with the ^M means that you have extra characters on the line. See here.
https://stackoverflow.com/tags/bash/info
Try putting the "shebang" line in the script shebang docs
To do this, run which bash which will tell you something like /bin/bash. Your script should then be:
#!/bin/bash
echo "I'm running with bash!"
Try that, your syntax is OK.

operand expected (Error token is "-") and ambiguous redirect

I have to errors, operand expected and ambiguous redirect.
Here's my code:
#!/bin/bash
read input >| inputfile
file_name=$(cut -d" " -f1 inputfile)
i=$(cut -d" " -f2 inputfile)
j=$(cut -d" " -f3 inputfile)
k=$(cut -d" " -f4 inputfile)
l=$(cut -d" " -f5 inputfile)
maxlinetoget=$[$l-$k]
currentlinecount=1
result=0
while read line
do
if [ $currentlinecount -ge $k && $currentlinecount -le $l ]
then
echo -n $line >| linefile
echo -n $line
for number in linefile
do
echo $number
result=$[$result+$number]
done
fi
currentlinecount=$[$currentlinecount+1]
done < $file_name
echo $result
And the errors:
./P4.4: line 8: -: syntax error: operand expected (error token is "-")
./P4.4: line 24: $file_name: ambiguous redirect
line 8 is: maxlinetoget=$[$l-$k]
line 24 is: done < $file_name
I have no idea what's wrong, please tell me.
Thanks.
Both errors are the result of the fact that neither $l not $file_name have a value. Bash sometimes produces mysterious error messages when unquoted variables are empty. (You would have gotten more sensible error messages if you'd used $((l-k)) instead of the deprecated $[$l-$k], or had quoted your substitutions, particularly "$file_name".)
read line >| inputfile
reads one line from stdin and puts it in the variable $line. It produces no output, so inputfile is empty. Consequently, all of the following cut commands produce no output (nothing-in, nothing-out: the infamous NINO).
What you apparently wanted to do was
read file_name i j k l rest
((maxlinetoget = l - k))
# Or maxlinetoget=$((l-k))

Getting error: sed: -e expression #1, char 2: unknown command: `.'

EDIT: FIXED. Now concerned with optimizing the code.
I am writing a script to separate data from one file into multiple files. When I run the script, I get the error: "sed: -e expression #1, char 2: unknown command: `.'" without any line number, making it somewhat hard to debug. I have checked the lines in which I use sed individually, and they work without problem. Any ideas? I realize that there are a lot of things that I did somewhat unconventionally and that there are faster ways of doing some things (I'm sure there's a way to avoid continuously importing somefile), but right now I'm just trying to understand this error. Here is the code:
x1=$(sed -n '1p' < somefile | cut -f1)
y1=$(sed -n '1p' < somefile | cut -f2)
p='p'
for i in 1..$(seq 1 $(cat "somefile" | wc -l))
do
x2=$(sed -n $i$p < somefile | cut -f1)
y2=$(sed -n $i$p < somefile | cut -f1)
if [ "$x1" = "$x2" ] && [ "$y1" = "$y2" ];
then
x1=$x2
y1=$x2
fi
s="$(sed -n $i$p < somefile | cut -f3) $(sed -n $i$p < somefile | cut$
echo $s >> "$x1-$y1.txt"
done
The problem is in the following line:
for i in 1..$(seq 1 $(cat "somefile" | wc -l))
If somefile were to have 3 lines, then this would result in following values of i:
1..1
2
3
Clearly, something like sed -n 1..1p < filename would result in the error you are observing: sed: -e expression #1, char 2: unknown command: '.'
You rather want:
for i in $(seq 1 $(cat "somefile" | wc -l))
This is the cause of the problem:
for i in 1..$(seq 1 $(cat "somefile" | wc -l))
Try just
for i in $(seq 1 $(wc -l < somefile))
However, you are reading your file many, many times too often with all those sed commands. Read it just once:
read x1 y1 < <(sed 1q somefile)
while read x2 y2 f3 f4; do
if [[ $x1 = $x2 && $y1 = $y2 ]]; then
x1=$x2
y1=$x2
fi
echo "$f3 $f4"
done < somefile > "$x1-$y1.txt"
The line where you construct the s variable is truncated -- I'm assuming you have 4 fields per line.
Note: a problem with cut-and-paste coding is that you introduce errors: you assign y2 the same field as x2

Resources