Trying to pass regular expression to grep - linux

I'm trying to exctract error lines from my log file:
I used this :
more report.txt | grep -E (?i)(error)
I'm getting this error msg :
bash: syntax error near unexpected token `('
What am I doing wrong? I'm trying to extract all lines containing "Error" ignoring the case sensitivity so it can be error, Error, ERROR etc.

The problem with your line is that the parens are picked up by the shell instead of grep, you need to quote them:
grep -E '(?i)(error)' report.txt
For this particular task the other answers are of course correct, you don't even need the parens.

You can do:
grep -i error report.txt
There is really no need to more the file and then pipe it to grep. You can pass the filename as an argument to grep.
To make the search case insensitive, you use the -i option of grep.
And there is really no need to go for -E option as the pattern you are using error is not an extended regex.
The cause of the error you are seeing is that your pattern (?i)(error) is interpreted by the shell and since the shell did not except to see ( in this context it throws an error, something similar to when you do ls (*).
To fix this you quote your pattern. But that will not solve your problem of finding error in the file because the pattern (?i)(error) looks for the string 'ierror' !!

you can use
grep -i error report.txt

this will achieve the same result
cat report.txt | grep -i error
and if you want to paginate the results:
cat report.txt | grep -i error | more

Related

grep the log file after running script and need to show the log file

I need to run the script grep the logfile and then show the log file. I have tried the following command
sh abc.sh | grep "Log File: "| sed -e s/'Log File (.*)$')
I got an error as: sed expression #1 unterminated s' command
The syntax of your sed command is invalid. It's not entirely clear to me what you are trying to do with that invalid sed, but I think you're looking for:
sh abc.sh | sed -n -e '/Log File:/s///p'
This will suppress all output except those lines which match the regex Log File:, and the text Log File: will be replaced with the empty string. (s///p will use the previous pattern for the match, and replace the first occurrence of that pattern with the empty string. The p flag causes the line to be printed.)

Not getting an sed error

Im trying to append a line in a file using following sed command
sed -i 's/id="1asda"/id="1asda"\n peer="120"/g' a.xml.
Now the problem is that even if I'm giving a wrong id, sed is not popping an error.How to get an error if the pattern is not found.
sed is used to replace text. Having nothing to replace is not an error.
Use something like grep to check whether there's something to replace or not. For example:
if grep -q 'id="1asda"' a.xml
then
sed -i 's/id="1asda"/id="1asda"\n peer="120"/g' a.xml
else
echo 'nothing to do' >& 2
fi
I would suggest to use awk:
awk 'BEGIN{e=1}gsub(/foo1/, "bar",$0){e=0};1;END{exit e}' file
The above command will give you a return value of 1 if no substitution has been performed, otherwise 0.

Searching log file for specific matching error code

How to search a unix log file for a specific error code and display only the variable that matches that search?I have tried using grep and egrep commands.
I am not sure you have tried this
grep TextYouWantToExclude YourLogfile.abc | grep -v ERROR
And did grep or egrep not work for you?
I use vim for this. The command :g/<search> comes in very handy because it filters out all lines that do not match <search>. <search> can be a regular expression just as one would use with grep.
grep -i error_code log_file
This will display all the instances of error code found in log file.

-bash: syntax error near unexpected token `done' in script

I am sorry for posting this but this is driving me crazy. I am very new to bash scripting and am really struggling. I have files with the following format 8_S58_L001.sorted.bam and I would like to take the first digit (8 in this case) from many files and generate a csv file. This will give me the order in which samples were processed by a downstream function.
The script is as follows and it works, however I get an error (-bash: syntax error near unexpected token `done') everytime I run it and am struggling to understand why. So far I have spent 2 days trying to get to the bottom of it and have searched extensively through various forums.
do
test=$(ls -LR | grep .bam$| sed 's/_.*//'| awk '{print}' ORS=',' | sed 's/*$//')
echo $test>../SampleOrder/fileOrder2.csv
done
If I just run
test=$(ls -LR | grep .bam$| sed 's/_.*//'| awk '{print}' ORS=',' | sed 's/*$//')
echo $test>../SampleOrder/fileOrder2.csv
Then I get the desired output and no errors but if it is incorporated within an do statement I get the above error. I am hoping to incorporate this into a larger script so I want to deal with this error first.
I should say that this is being run on a linux based cluster.
Can someone with more experience tell me where I am going wrong.
Thanks in advance
Sam
bash doesn't have a do statement, and done is a reserved word when it is the first word in a command.
So in
do
something
something
done
do is a syntax error. do is only useful in the context of for and while loops, where it serves to separate the condition from the body of the loop.
Since you're reporting a syntax error on the done as opposed to the do, my guess is that you've let Windows line-endings creep into your file. Bash doesn't regard the \r (CR) character as special, so if your file actually contains do\r, then that will be considered to be the name of an external command.
You should be aware that grep .bam$ doesn't do what you are expecting it to do. The dot is a grep wildcard which matches any single character, so the pattern .bam$ will match any string of 4 or more characters that ends in "bam". If you are trying to match all strings that end in ".bam", you should escape the dot and write grep "\.bam$"
But as a previous commenter correctly noted, you should be using shell wildcards (ls *.bam) instead of grep (ls | grep .bam$)

Simple BASH string replacement

I'm trying to replace instances of {$pear_root} in a config file with the $PEAR_ROOT variable in a shell script.
Using the method from here under "A Note About Bash Escape Character" I have:
ESC_PEAR_ROOT="${PEAR_ROOT//\//\\/}"
sed -i "s/{\$pear_root}/${ESC_PEAR_ROOT}/"../.serverconfig/test.txt
I'm getting back 34: Bad substitution which I think may mean that this is unsupported.
The problem seems to be the use of s/find/replace/, as I get the same error whether doing this with sed or with perl.
What is the simplest way to do this:
APP_ROOT=$(php ./scripts/get_realpath.php '../')
PEAR_ROOT="$APP_ROOT/pear"
ESC_PEAR_ROOT="${PEAR_ROOT//\//\\/}"
sed -e "s/{\$pear_root}/${ESC_PEAR_ROOT}/"../.serverconfig/test.txt
And end up with all instances of {$pear_root} in test.txt replaced with the path from PEAR_ROOT?
I'm not attached to this method - anything reliable will do.
This is a bit silly, but I notice you're missing a space between the end of your expression and the name of the file to which you wish to apply it.
/tmp $ sed -e 's/{$pear_root}/'"$PATH"'/' test
/tmp $ sed -e 's/{$pear_root}/'"$PATH"'/'test
sed: bad option in substitution expression
Ok, solved it.
The problem was:
This:
ESC_PEAR_ROOT="${PEAR_ROOT//\//\\/}"
Should have been this:
ESC_PEAR_ROOT="{PEAR_ROOT//\//\\/}"
That was what was causing my "bad substitution" error.
Also, realized I didn't need to escape, since I could just use a different delimiter to s, so I don't even need that line.
Final result ended up as:
APP_ROOT=$(php ./scripts/get_realpath.php '../')
PEAR_ROOT="$APP_ROOT/pear"
sed -i "s#{\$pear_root}#${PEAR_ROOT}#g" ../.serverconfig/test.txt

Resources