How to add output non_assigned when there is no match in grep?
This will do the job:
for p in $(<input.txt)
do
(COMMAND $p | grep -w "phylum") || echo "non_assigned"
done >> results.txt
This runs the command and the grep
in a subshell. If the grep
finds 'phylum', the RHS of the ||
is not run; if 'phylum' is not found, the echo
is executed to output a suitable marker.
Notice that the redirection has been moved to after the done
; it might be better to use >
rather than >>
now.
Beware the set
option -o pipefail
— if the command can fail, you might need to use set +o pipefail
. However, it is disabled by default, so you'll probably be OK.
grep a pattern and output non-matching part of line
How about using a combination of grep
, sed
and $PIPESTATUS
to get the correct exit-status?
$ echo Humans are not proud of their ancestors, and rarely invite
them round to dinner | grep dinner | sed -n "/dinner/s/dinner//p"
Humans are not proud of their ancestors, and rarely invite them round to
$ echo $PIPESTATUS[1]
0[1]
The members of the $PIPESTATUS
array hold the exit status of each respective command executed in a pipe. $PIPESTATUS[0]
holds the exit status of the first command in the pipe, $PIPESTATUS[1]
the exit status of the second command, and so on.
grep operation with ? pattern
With no flags to indicate the input is a regex, it has no special meaning.
Test:
~$ echo "hello ? world" | grep " ? "
hello ? world
Test with the -q
flag:
~$ echo "hello ? world" | grep -q " ? "; echo $?
0
$?
holds the exit status of the last command. grep
was the last command before echo
, and it returns 0 when it matches.
If you try a non-matching string, you'll get:
~$ echo "hello world" | grep -q " ? "; echo $?
1
“How to fix ‘sed + grep no return status when no match’ error in shell”
#!/bin/sh -e
This set's the set -e
flag. From posix shell set manual emphasis mine:
-e
When this option is on, if a simple command fails for any of the reasons listed in Consequences of Shell Errors or returns an exit
status value >0, and is not part of the compound list following a
while, until, or if keyword, and is not a part of an AND or OR list,
and is not a pipeline preceded by the ! reserved word, then the shell
shall immediately exit.
From man grep:
Normally the exit status is 0 if a line is selected, 1 if no lines
were selected, and 2 if an error occurred.
As the command grep
in the pipeline inside a command substitution returns a non-zero status:
x=`
eval sed -n -e '1,"$"p' test.txt | # will not print any googoog
grep "googoo" # thus this will return with 1
` # command substitution exit status is the exit status of the last command executed
# the last command executed is grep - so command's substitution exit status is 1
# the exit status of variable assignment is the exit status of the last command executed
# the last command executed is command substitution - it's exit status was 1
The command returns with nonzero status, which terminates your script.
Notes:
- Eval is evil, unneeded there, and using it is bad. Just
sed -n -e '1,'"$p" test.txt
... - Using backticks is deprecated. Don't use backticks. Use
$( ... )
, which looks cleaner, more readable, allows for nesting. - Remember about
-e
shell flag. Use it wise and learn to handle exit statuses from commands.
grep return 0 if no match
The actual answer to this question is to add || true
to the end of the command, e.g.:
echo thing | grep x || true
This will still output a 0 return code.
Grep and other programs not found in script
$PATH is a special variable to the shell. It defines the list of directories to be searched when executing subcommands.
Bash won't know where grep, awk or chown are. Please use different variable name instead of $PATH.
Try
#!/bin/bash
# Script for getting all TODOS
xPATH="~/documents/obsidian-notes/"
OUTPUT="/home/fish/documents/obsidian-notes/TODO.md"
echo "#TODO" > $OUTPUT
grep -hr --exclude-dir=plugins "\bTODO\b:.*" $xPATH | awk '{print $0,"\n"}' >> $OUTPUT
What is assigned to a variable if 'grep' doesn't return anything?
If grep
returns nothing, the $test_avd
variable would be empty. But there's no need for a variable here.
Instead of this:
test_avd=$(android list avd | grep test)
if [ ! -z $test_avd ]
Use this:
if android list avd | grep -q test
Note: when variables are needed, the ! -z
is also needless; [ "$test_avd" ]
returns exactly the same result as [ ! -z $test_avd ]
.
grep command always includes html tag with matching output
As per a related question here and use of extended and perl patterns in grep (and egrep). You would have to use a regular expression which returns only the matched group (the text of tag) sth like this (not tested):
grep -oP '<[a-zA-Z]+> \K\[^<]+' test.txt
What the regex above does is return the text of the tag only, as matched group and reject any open close tags
grep extended patterns
Related Topics
Gnuplot Doesn't Work Through Ssh Command
How to Configure Acpi *.Asl for a Virtual Mdio-Gpio Device Connected to a I2C Gpio Expander
Run Bash Script in Raspberry Pi via Ifttt
Stack Smashing Code Not Working on Linux Kernel 2.6.38.7... Please Help
How to Share a Register Between Threads
Gfortran Linking C Libraries with Conda
Focas Fwlib32 Cnc Library on Linux Platform
Native Linux App to Edit Win32 Pe Like Reshacker
Sort Entries of Lines Using Shell
Average of Multiple Files Without Considering Missing Values
Will Process Lost Wake-Up Chance in a Preemptive Kernel
Ssh Connection to Ubuntu Open Ssh-Server Requires Login on (Physical) Server via Password First
Bash Assign Output to Variable Inside Here Document
Docker-Compose Stop Working After Docker Desktop Installation on Debian 11
Wc -M in Unix Adds One Character
Linux Ipc: Shared Memory Recovery
Command Substitution Doesn't Work in Script Text Passed Over Ssh