dynamic exclusion of files through grep matching - grep

I have a file source-push.sh which returns the list of files which I want to exclude from the results of find command.
It looks like this:
#!/usr/bin/env bash
find . -not \( -path './node_modules' -prune \) -name '*.js' | grep -vE $(echo $(./source-push.sh | xargs -I{} echo -n "{}|") | rev | cut -b2- | rev) | xargs -L1 standard --fix
find . -not \( -path './node_modules' -prune \) -name '*.css' | grep -vE $(echo $(./source-push.sh | xargs -I{} echo -n "{}|") | rev | cut -b2- | rev) | xargs -L1 stylelint --config stylelint.json
There are supposed to be a way to do the job better than that. Any suggestions?

Instead of:
... | grep -vE $(echo $(./source-push.sh | xargs -I{} echo -n "{}|") | rev | cut -b2- | rev ) | ...
you can use the POSIX options -F and -f:
... | grep -v -F -f <( ./source-push.sh ) | ...
-F tells grep that the patterns are fixed strings
(avoiding the problem that your original code would break if the patterns contain characters that are special to grep -E)
-f file tells grep to use a list of patterns from file
<( ... ) is a bash way to present output of a program as a file (named pipe)

Related

How to search for 2 key words from files in a directory and print their filename if it occurs more than once

I am trying to grep or find for 2 specific words in each file in a directory. And then If i find more than one file found with such a combination - only then I should print those file names to a CSV file.
Here is what I tried so far:
find /dir/test -type f -printf "%f\n" | xargs grep -r -l -e 'ABCD1' -e 'ABCD2' > log1.csv
But this will provide all file names that have "ABCD1" and "ABCD2". In other words, this command will print the filename even if there is only one file that has this combo.
I will need to grep the entire directory for those 2 words and both words MUST be in more than one file if it has to write the filenames to CSV. I should also be able to include sub directories
Any help would be great!
Thanks
find + GNU grep solution:
find . -type f -exec grep -qPz 'ABCD1[\s\S]*ABCD2|ABCD2[\s\S]*ABCD1' {} \; -printf "%f\n" \
| tee /tmp/flist | [[ $(wc -l) -gt 1 ]] && cat /tmp/flist > log1.csv
Alternative way:
grep -lr 'ABCD2' /dir/test/* | xargs grep -l 'ABCD1' | tee /tmp/flist \
| [[ $(wc -l) -gt 1 ]] && sed 's/.*\/\([^\/]*\)$/\1/' /tmp/flist > log1.csv

grep -v under double quotes query

We have a portion of code which states,
"diff file1 file2 | /usr/bin/grep -v "#" | /usr/bin/grep ^\> | /usr/bin/awk '{print $3}' | /usr/bin/xargs mkdir"
The whole statement is enclosed in double quotes(is a requirement of the application syntax). When the application reaches this stage , it gives the grep error.
This statement works well on the command line. But through application, gives error for grep.
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.
So not sure if it is first grep or second grep which is a problem.
Seems like a problem with double quotes. Try changing your first grep to /usr/bin/grep -v '#' and the second grep to /usr/bin/grep '^>'
You are using grep -v ^> and > means "redirect".
If you for example do:
grep ^>output
all the output will be stored in the file output.
So what you need to do is to quote ^> so that it is interpreted as the pattern you are looking for:
"diff file1 file2 | /usr/bin/grep -v "#" | /usr/bin/grep "^>" | /usr/bin/awk '{print $3}' | /usr/bin/xargs mkdir"
^ ^
By the way, note all your greps can be reduced like this:
diff file1 file2 | awk '/#/ || /^>/ {print $3}' | /usr/bin/xargs mkdir
^^^ ^^ ^^^^
either contains # | |
or starts with >

How do i Extract integer value from a string in Unix

when i type this command
/usr/local/afs7/bin/afs_paftools -a about.afs | grep TOTAL_DOCUMENTS
I get a result
TOTAL_DOCUMENTS = 74195
How i can extract the integer number(74195) after =
using grep command
One way is to use grep:
$ echo "TOTAL_DOCUMENTS = 74195" | grep -o '[0-9]\+'
74195
or since you know, that it's the last field, use awk:
$ echo "TOTAL_DOCUMENTS = 74195" | awk '{print $NF}'
74195
or just use awk for the lot:
your-command -a about.afs | awk '/TOTAL_DOCUMENTS/{print $NF}'
If there are no space:
TOTAL_DOCUMENTS=74195
Use this awk
echo "TOTAL_DOCUMENTS=74195" | awk -F= '{print $NF}'
74195

xargs: String concatenation

zgrep -i XXX XXX | grep -o "RID=[0-9|A-Z]*" |
uniq | cut -d "=" -f2 |
xargs -0 -I string echo "RequestID="string
My output is
RequestID=121212112
8127127128
8129129812
But my requirement is to have the request ID prefixed before all the output.
Any help is appreciated
I had a similar task and this worked for me. It might be what you are looking for:
zgrep -i XXX XXX | grep -o "RID=[0-9|A-Z]*" |
uniq | cut -d "=" -f2 |
xargs -I {} echo "RequestID="{}
Try -n option of xargs.
-n max-args
Use at most max-args arguments per command line. Fewer than max-args arguments will be used if the size (see the -s option)
is exceeded,
unless the -x option is given, in which case xargs will exit.
Example:
$ echo -e '1\n2' | xargs echo 'str ='
str = 1 2
$ echo -e '1\n2' | xargs -n 1 echo 'str ='
str = 1
str = 2

tail pipe grep pipe xmllint not working

I'm trying to get the below command working but no o/p is getting printed:
tail -f mylog.log | grep --line-buffered -Eo '<S:Envelope .+Envelope>' | xmllint --format --recover -
However, if I grep the same pattern from a file, and pipe it to xmllint, it works:
grep --line-buffered -Eo '<S:Envelope .+Envelope>' tmp.xml | xmllint --format --recover -
What am I missing in the first command?
Can you try this (untested):
tail -f mylog.log | grep -Eo '<S:Envelope .+Envelope>' | while read line; do
echo $line | xmllint --format --recover -
done
(that is under the hypothesis that xmllint does not find EOF and as such is still waiting for input)
Try something like this -
grep --line-buffered -Eo '<S:Envelope .+Envelope>' <(tail -f mylog.log) &1> xmllint --format --recover -

Resources