How to save results to file usig putty grep - grep

I log in by Putty (ssh) to FTP.
Need to find in all files this string style="position:absolute;top:-8888px;left:-2900px;z-index:0;".
If I type:
grep 'position:absolute;top:-8888px;'
it gave me some results.
Then try to save to a file 'raport.txt' like this:
grep 'position:absolute;top:-8888px;' * -R >>raport.txt
Permissions are 777.
Grep only creates the file and saves nothing.
What am I doing wrong?

grep 'position:absolute;top:-8888px;' * -R >>raport.txt
^^
It's possible that grep isn't searching all of the files that you expect it to, because the -R option (search subdirectories recursively) is in the wrong place. For most programs, including grep, options like -R should come before the non-option arguments.
In other words, try running it with -R at the beginning, like this:
grep -R 'position:absolute;top:-8888px;' * >>raport.txt
^^

Related

Remove directory path from grep -r output

I am running grep -r to look for the context of a word in multiple files.
I am using -r to do it recursively, -i to ignore case and -C to get lines below and above:
grep -r -i -C 10 --group-separator="==========" "29/04/2020" "$dir" >> output.txt
In my output, however, I get the filenames before the match, like:
../data/filename1.txt- (other text)
../data/filename1.txt- 29/04/2020 is the date for etc
../data/filename1.txt- (other text)
==========
../data/different_filename.txt- (other text)
../data/different_filename.txt- something in 29/04/2020
../data/different_filename.txt- (other text)
I would like as output just:
(other text)
29/04/2020 is the date for etc
(other text)
==========
(other text)
something in 29/04/2020
(other text)
Do you know how I could alter the grep -r command to exclude the filepaths?
Use grep -h, as described in man grep:
-h
--no-filename
Suppress the prefixing of file names on output. This is the default when there is only one file (or only standard input) to
search.
SEE ALSO:
Get grep to not output file name

Combine grep -v with grep -r?

I want to remove an entire line of text from all files in a given directory. I know I can use grep -v foo filename to do this one file at a time. And I know I can use grep -r foo to search recursively through a directory. How do I combine these commands to remove a given line of text from all files in a directory?
The UNIX command to find files is named find, not grep. Forget you ever heard of grep -r as it's just a bad idea, here's the right way to find files and perform some action on them:
find . -type f -print | xargs sed -i '/badline/d'
Try something like:
grep -vlre 'foo' . | xargs sed -i 's/pattern/replacement/g'
Broken down:
grep:
-v 'Inverse match'
-l 'Show filename'
-r 'Search recursively'
-e 'Extended pattern search'
xargs: For each entry perform
sed -i: replace inline
I think this would work:
grep -ilre 'Foo' . | xargs sed -i 'extension' 'Foo/d'
Where 'extension' refers to the addition to the file name. It will make a copy of the original file with the extension you designated and the modified file will have the original filename. I added -i in case you require it to be case insensitive.
modified file1 becomes "file1"
original file1 becomes "file1extension"
invalid command code ., despite escaping periods, using sed
One of the responses suggests that the newer version of sed's -i option in OSX is slightly different so you need to add an extension. The file is being interpreted as a command, which is why you are seeing that error.

How to use grep to search only in a specific file types?

I have a lot of files and I want to find where is MYVAR.
I'm sure it's in one of .yml files but I can't find in the grep manual how to specify the filetype.
grep -rn --include=*.yml "MYVAR" your_directory
please note that grep is case sensitive by default (pass -i to tell to ignore case), and accepts Regular Expressions as well as strings.
You don't give grep a filetype, just a list of files. Your shell can expand a pattern to give grep the correct list of files, though:
$ grep MYVAR *.yml
If your .yml files aren't all in one directory, it may be easier to up the ante and use find:
$ find -name '*.yml' -exec grep MYVAR {} \+
This will find, from the current directory and recursively deeper, any files ending with .yml. It then substitutes that list of files into the pair of braces {}. The trailing \+ is just a special find delimiter to say the -exec switch has finished. The result is matching a list of files and handing them to grep.
If all your .yml files are in one directory, then cd to that directory, and then ...
grep MYWAR *.yml
If all your .yml files are in multiple directories, then cd to the top of those directories, and then ...
grep MYWAR `find . -name \*.yml`
If you don't know the top of those directories where your .yml files are located and want to search the whole system ...
grep MYWAR `find / -name \*.yml`
The last option may require root privileges to read through all directories.
The ` character above is the one that is located along with the ~ key on the keyboard.
find . -name \*.yml -exec grep -Hn MYVAR {} \;

How can I have grep not print out 'No such file or directory' errors?

I'm grepping through a large pile of code managed by git, and whenever I do a grep, I see piles and piles of messages of the form:
> grep pattern * -R -n
whatever/.git/svn: No such file or directory
Is there any way I can make those lines go away?
You can use the -s or --no-messages flag to suppress errors.
-s, --no-messages suppress error messages
grep pattern * -s -R -n
If you are grepping through a git repository, I'd recommend you use git grep. You don't need to pass in -R or the path.
git grep pattern
That will show all matches from your current directory down.
Errors like that are usually sent to the "standard error" stream, which you can pipe to a file or just make disappear on most commands:
grep pattern * -R -n 2>/dev/null
I have seen that happening several times, with broken links (symlinks that point to files that do not exist), grep tries to search on the target file, which does not exist (hence the correct and accurate error message).
I normally don't bother while doing sysadmin tasks over the console, but from within scripts I do look for text files with "find", and then grep each one:
find /etc -type f -exec grep -nHi -e "widehat" {} \;
Instead of:
grep -nRHi -e "widehat" /etc
I usually don't let grep do the recursion itself. There are usually a few directories you want to skip (.git, .svn...)
You can do clever aliases with stances like that one:
find . \( -name .svn -o -name .git \) -prune -o -type f -exec grep -Hn pattern {} \;
It may seem overkill at first glance, but when you need to filter out some patterns it is quite handy.
Have you tried the -0 option in xargs? Something like this:
ls -r1 | xargs -0 grep 'some text'
Use -I in grep.
Example: grep SEARCH_ME -Irs ~/logs.
I redirect stderr to stdout and then use grep's invert-match (-v) to exclude the warning/error string that I want to hide:
grep -r <pattern> * 2>&1 | grep -v "No such file or directory"
I was getting lots of these errors running "M-x rgrep" from Emacs on Windows with /Git/usr/bin in my PATH. Apparently in that case, M-x rgrep uses "NUL" (the Windows null device) rather than "/dev/null". I fixed the issue by adding this to .emacs:
;; Prevent issues with the Windows null device (NUL)
;; when using cygwin find with rgrep.
(defadvice grep-compute-defaults (around grep-compute-defaults-advice-null-device)
"Use cygwin's /dev/null as the null-device."
(let ((null-device "/dev/null"))
ad-do-it))
(ad-activate 'grep-compute-defaults)
One easy way to make grep return zero status all the time is to use || true
→ echo "Hello" | grep "This won't be found" || true
→ echo $?
0
As you can see the output value here is 0 (Success)

Automatically ignore files in grep

Is there any way I could use grep to ignore some files when searching something, something equivalent to svnignore or gitignore? I usually use something like this when searching source code.
grep -r something * | grep -v ignore_file1 | grep -v ignore_file2
Even if I could set up an alias to grep to ignore these files would be good.
--exclude option on grep will also work:
grep perl * --exclude=try* --exclude=tk*
This searches for perl in files in the current directory excluding files beginning with try or tk.
You might also want to take a look at ack which, among many other features, by default does not search VCS directories like .svn and .git.
find . -path ./ignore -prune -o -exec grep -r something {} \;
What that does is find all files in your current directory excluding the directory (or file) named "ignore", then executes the command grep -r something on each file found in the non-ignored files.
Use shell expansion
shopt -s extglob
for file in !(file1_ignore|file2_ignore)
do
grep ..... "$file"
done
I thinks grep does not have filename filtering.
To accomplish what you are trying to do, you can combine find, xargs, and grep commands.
My memory is not good, so the example might not work:
find -name "foo" | xargs grep "pattern"
Find is flexible, you can use wildcards, ignore case, or use regular expressions.
You may want to read manual pages for full description.
after reading next post, apparently grep does have filename filtering.
Here's a minimalistic version of .gitignore. Requires standard utils: awk, sed (because my awk is so lame), egrep:
cat > ~/bin/grepignore #or anywhere you like in your $PATH
egrep -v "`awk '1' ORS=\| .grepignore | sed -e 's/|$//g' ; echo`"
^D
chmod 755 ~/bin/grepignore
cat >> ./.grepignore #above set to look in cwd
ignorefile_1
...
^D
grep -r something * | grepignore
grepignore builds a simple alternation clause:
egrep -v ignorefile_one|ignorefile_two
not incredibly efficient, but good for manual use

Resources