Using find and grep to Mimic findstr Command [closed] - macos

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I recently switched from a Windows development environment to an Apple development environment. The move has been a challenging process, but I'm struggling with picking up UNIX based commands in terminal to makeup for the commands I used on a daily basis in Windows command prompt. Any help would greatly appreciated, explanations on a basic level of what's going on in the commands provided is a huge bonus for me as I'm trying to get a grasp on the UNIX commands, but reading the manual is like reading a foreign language to me most of the time.
Here's my question: Is there a single line command, preferably short enough to memorize, that I can execute to mimic or produce very similar output to the following Windows CMD command:
findstr /s /c:"this piece of text" *.code
I use this command on Windows often to produce a result set that shows me where the text between the quotes resides in any of the files matching the *.code pattern in any subdirectories. This can be used to check version numbers of numerous files pulled back from servers to looking for where a variable was declared in a large project. The output comes in this form:
file1.code: other text this piece of text other text
file2.code: other text this piece of text other text
file3.code: other text this piece of text other text
file4.code: other text this piece of text other text
file5.code: other text this piece of text other text
Where other text is any other text found on the same line as my search string in the given file. I have searched through the questions here and found several people using find . -name *.code to build a list of files in the subdirectories. They then use the -exec flag from the find command paired with a grep sequence to search text. I tried this in several of the mentioned ways and was failing, I think due to escape sequences or missed characters. It would be awesome if there was a way to just give the command a string in between quotes that it just searched for as is.
I tried the following and wasn't getting any results... Maybe a syntax error?
find . -exec grep -H .getItemToChange().getItemAttributes()
UPDATE
The correct code is provided below with a great explanation by John. If this helps you like it helped me give his answer an upvote!
I was hoping to find the .java file with this function call in it in a large project. It wasn't giving me any results and it also didn't have a way to filter to only *.java.
Can anyone help me out here? Explanations to your commands are GREATLY appreciated.

find . -name '*.code' -exec grep -H 'pattern' {} +
Make sure to quote '*.code' so the shell doesn't expand the * wildcard. Usually we do want the shell to do the expansion, but in this case we want the literal string *.code to be passed to find so it can do the wildcard expansion itself.
When you use -exec you need to put {} somewhere; it's the placeholder for the file names that are found. You also need either \; or + at the end of the command. It's how you signal to find where the end of -exec's arguments are (it's possible to have other actions following -exec). \; will cause grep to be run once for each file while + runs a single grep on all of the files.
find . -name '*.code' -print0 | xargs -0 grep -H 'pattern'
Another common way to do this is by chaining together find and xargs. I like using -exec better, but find+xargs works just as well. The idea here is that xargs takes file names passed in on stdin and runs the named command with those file names appended. To get a suitable list of file names passed in we pipe the output of a find command into xargs.
The -print0 option tells find to print each file it finds along with a NUL character (\0). This goes hand in hand with xargs's -0 option. Using -print0 and -0 ensures that we can handle file names with unusual characters like whitespace and quotes correctly.

Related

terminal commands to get hidden files ending with a particular pattern

I can easily search for non-hidden files in terminal ending with a particular pattern.
*for example*
Consider these files are present in the folder in which I am searching
1new 2new 3new 4new .5new
If I enter the command la *ew I get these files as output
1new 2new 3new 4new
I am getting the same result when using ls -a *ew
So what command should I enter in order to get hidden files ending with a particular pattern.
ls does not support regular expressions as per my understanding. So, you might need to pipe the output to some other command like grep which supports regular expressions. Try below command and see if it works as per your need.
ls -a | grep new
Refer this post for more information.

How to limit the depth of the directory visited by the Unix command find?

Similar question has already been asked but I am not satisfyed with the answers. Indeed, I want to use the Unix find command and the find command I use does not allow the option -maxdepth. However, there is an option -depth but I did not succed to use it in a way that I am satisfied. I use ksh shell.
You can limit the listing if you add the grep command like this example:
find $mydir -name "BILL_*.pdf" | grep "$mydir/BILL"
Good luck...
Refer find manual
-depth Always evaluates to the value True. Causes the descent of the
directory hierarchy to be done so that all entries in a directory are
affected before the directory itself is affected. It can be useful
when the find command is used with the cpio command to transfer files
that are contained in directories without write permission.
So it does not accept an argument.

searching in the source code

Often I do different projects and sometimes there is a lack of documentation.
So I decided to use open-source code for looking how people solved different problems.
The idea is if I run into function what I don't how to use I look for different developers used that function before.
Approach:
I downloaded a few pretty decent projects done by other people and put them into one folder.
Now, if I don't know how a function is used (e.g. main() ), I do :
find . -name \*.py | xargs cat | grep -n "main()"
Consequently I get examples of its use:
But there is a problem. I don't know from which file examples are. It'd be perfectly if it was possible to get name of the file as well as number of line.
It seems to be limitation of use "cat" command because it mixes all files together and as result I get information about number not in the file but rather in cat output. So I feel this approach is bad in the root.
i.e.
I want to be able to look for functions/symbols in plethora of source code
and get information about the line and file where a certain combination was met.
I prefer console-way.
Any advice?
Try this:
find . -name \*.py -exec grep -nH "main()" {} \;
Explanation:
The "-exec" option says to execute the following command, up until \; for each file it finds.
The "-H" option to grep causes it to print the name of the file in which the string was found.
The "-n" option causes grep to print the line numbers.
The {} is a placeholder that expands to the name of the file that "find" just found.
You need only grep command:
$ grep -nr 'main()' /path/to/projects/folder/* | grep '.py:'
Want to search source files ? Why not http://beyondgrep.com/ ?
I wont answer you from the point of the bash.
I dont know which editor/IDE are you using, but for code dissecting there is no better tool for me then:
Vim with Ctags combination
Ctrl-p,Ctrl-p funky and MRU plugin +
proper search and regex usage.
good vim debugger
There is no part of code that cant be examined. Please sorry if are using some other tools, I am just suggesting you what do I find is the best for code analysis for me.

ubuntu bash script to identify files in subfolders, pass them onto external program and create a text file for each input file [duplicate]

This question already has answers here:
Getting an "ambiguous redirect" error
(14 answers)
Closed 8 years ago.
I have very little understanding of bash scripting. I need to recurse through a folder and its subfolders, identify png files, pass them to an external linux application and capture the output of that application in a text file with the text file's first name being same as the file that was passed to the external program. Also the txt file has to be created in the same folder as the png file.
After searching through SO and googling I have come up with the following script
#!/bin/sh
cd folder1/folder2
find . -maxdepth 4 -iname '*.png' -type f |while read line; do
fullfilename="${line##*/}";
base="${fullfilename%.*}";
ext="${fullfilename##*.}";
mypath="${line%/*}";
#echo $fullfilename;
#echo $base;
#echo $ext;
#echo $mypath;
#echo $mypath/$base.txt;
#echo $line;
myexternalprogram -x $line > $mypath/$base.txt;
# -x is a switch reqd by the external program
done
Several of the subfolders of folder2 have white spaces in their names
e.g. Sub Folder 12
Running the above gives an error
...line 16: $mypath/$base.txt. ambigous redirect
Just to check i removed the redirect portion on line 16. I got the error
./subfolder1/subfolder2/Sub is an unknown extension
thrown by myexternal program obviously because it stuck at the white spaces in subfolder name.
Can anyone help me out please? What am I doing wrong?
Try putting quotes around the file names:
myexternalprogram -x "$line" > "$mypath/$base.txt";
Just quote "$line" to get rid of the whitespace problem.
Solved. Thanks to everyone who took time to read and help me.
It was the quotes i.e. quotes which i get when i type from my keyboard seem to be different from the quotes that i get when copy paste from SO.
The lines
fullfilename="${line##/}";
base="${fullfilename%.}";
ext="${fullfilename##*.}";
had been copy pasted from different SO posts / googled blogs. (Remember i have very little undertanding of bash :D ) These lines seem to have a different type of quote than the line
mypath="${line%/*}";
which i had typed from my keyboard.
I seem to have only one type of quotes on my keyboard which is ".
Even though it looks same on openoffice word processor, opening my bash file in gedit threw up the difference!!
Hence I copied the quotes from fullfilename line and pasted them into my mypath line and Viola!!
Can anyone enlighten me how come there are two types of quotes? I have never encountered this before.

How can you open files which contain the word "exam" in terminal?

I want to open many pdf -files which contain the word exam.
My Mac's terminal uses Bash.
The word exam is randomly in the name: sometimes at the beginner, sometimes at the midlle and sometimes at the end of the name.
How can you open files which contain the word "Exam" in terminal?
find . -name "*exam*" -exec <name of pdf reader executable> {} \;
Don't parse ls. It's output is not reliable and it's only made to look at (for human parsing). See http://mywiki.wooledge.org/ParsingLs.
Don't use xargs. It mangles your data trying to be smarter. Got spaces or quotes in your filenames? You can be sure that it'll explode.
To make xargs behave, you'd have to go to great lengths:
printf '%s\0' *Exam* | xargs -0 open
Yes, that's rather convoluted. Read on.
The find solution, while accurate, is recursive (might be what you want), but also a bit much to type in a prompt.
find . -name '*Exam*' -exec open {} +
You can make all that a lot easier by remembering that open on Mac OS X takes multiple arguments just fine (which is exactly what xargs does), so this is just fine for opening all documents in the current directory that contain the word Exam:
open *Exam*
Something like
acroread *Exam*.pdf
should work. This matches any string that has "Exam" in it, and ends with ".pdf". This also assumes that you have a command called "acroread" that knows how to read PDF:s, that may or may not be true for Mac OS X.
I would use:
ls *Exam* | xargs open

Resources