grep alias search command not working - grep

I am trying to make an alias called File Search (fs) for short. That takes one argument (search term). It then searches down the directory tree for that using grep.
Example:
fs 'function my_function()'
What am I doing wrong?
alias fs='grep -R "$1" .'

What you tried would search the current directory itself, not the files in it, and certainly not the files in its subdirectories. You want something like this (from memory, I'm not at a Unix machine right now):
find . -type f | xargs grep "$1"

Related

Mingw64 shell's grep ignores -r option?

I'm trying to do a grep in Microsoft Windows, using the MINGW64 shell v4.4.23(1). (That's what the title bar says. I assume this means MingW-W64.)
I want to list all files in a specified directory tree that have a certain filename extension and do not contain a certain string.
With the current directory set to the top of the tree I entered
grep -r -L thestring *.theextension
It lists only files in the current directory, not the tree.
I tried some variations and determined that grep is simply ignoring the -r option. It ignores --recursive, too.
But when I enter grep --help, it lists both -r and --recursive as valid options, with the expected meaning.
Is this a bug in the shell, or am I doing something stupid?
With grep -r -L thestring *.theextension you are telling grep to search recursively in any file or folder matching *.theextension. If you don't have any folders matching that you shouldn't expect it to go through any other folders. The -L flag doesn't mean it's going to look at anything not matching *.theextension, maybe that's what was confusing you...

grep recursive filename matching (grep -ir "xyz" *.cpp) does not work

while
grep -ir "xyz" * recursively searches through the directories and tell me that the text is present in ./x/y/z/abc.cpp
However ,
grep -ir "xyz" *.cpp offers no result.
Isn't the second command supposed to recursively grep all cpp files inside the directory ?
What am I missing here?
Grep will recurse through any directories you match with your glob pattern. (In your case, you probably do not have any directories that match the pattern "*.cpp") You could explicitly specify them: grep -ir "xyz" *.cpp */*.cpp */*/*.cpp */*/*/*.cpp, etc. You can also use the --include option (see the example below)
If you are using GNU grep, then you can use the following:
grep -ir --include "*.cpp" "xyz" .
The command above says to search recursively starting in current directory ignoring case on the pattern and to only search in files that match the glob pattern "*.cpp".
OR if you are on some other Unix platform, you can use this:
find ./ -type f -name "*.cpp" -print0 | xargs -0 grep -i "xyz"
If you are sure that none of your files have spaces in their names, you can omit the -print0 argument to find and the -0 to xargs
The command above says the following: find all files (-type f) under the current directory (./) that match the name glob/wildcard "*.cpp" (-name "*.cpp") and then print them out delimited by a null (-print0). That list of files found should be written to the stdin of the next command: xargs. xargs should read from stdin (default behavior) and split its input on nulls (-0) and then call the grep command with the specified options (grep -i "xyz") on that list of files.
If you are interested in learning more about why grep -ir "xyz" *.cpp does not work the way you think it should, you should search for "shell globbing" (here is a good first article on the subject). I'll also try to provide a quick explanation. When you type in the command grep -ir "xyz" *.cpp and hit enter, there are two programs that are involved in executing your command. The first program is your shell (and unless you've done something to customize things, you are probably usually the bash shell - if you've never heard of a shell or bash, that's where you should start looking, there are tons of good articles). Suffice it say that a shell is just a program that is designed to let you navigate the filesystem on your computer and run other programs. (In Windows, when you double click on an icon to launch a program, or open a folder to access a file, the program that you are running is explorer.exe and it is the Windows graphical shell). So, when you type the command grep -ir "xyz" *.cpp, before grep is run, the shell handles reading your command and does a few things. One of the things is does is expand glob patterns (things like *.txt or [0-9]+.pdf). Like I said, if you want to understand it, go read more about it, but the thing you should take away is that the grep command never sees the *.cpp. What happens is, the shell looks in the current directory for any files or directories with a name that match the pattern *.cpp and then replaces them on the command line BEFORE it runs the grep command. (If it doesn't find anything that matches, then it will leave the *.cpp there and grep will see it, but grep because doesn't normally do glob matching, this doesn't do anything for you).
Alternatively, when you type in grep -ir "xyz" *, what happens is that the shell replaces the * with the name of every file and directory in the current directory (because * matches anything). Let's say you had a directory that contained file1, file2, and dir1, and dir2, then the shell would perform its replacements and then execute a command that looked like this grep -ir "xyz" file1 file2 dir1 dir2, which means grep would search file1 and file2 for a line with the string xyz, and because of the -ir it also search recursively through dir1 and dir2 and search any files found for that string as well. Lastly, if you've followed everything I've said so far, then it will make sense to you that grep does have a way to use glob patterns on recursive searches, and that is to use the --include option, as in the command I described earlier: grep -ir --include "*.cpp" "xyz" ., and the reason why we put the *.cpp in quotes in that command is to prevent the shell from trying to expand the glob pattern before we run the command.

how to extract string from all c files in a folder using gettext

I'm trying to localize a 'C' project but I have no idea how to extract Strings by xgettext . And project has so many C files so extracting one by one is not feasible. S is it possible to extract strings from all files once. or there is any other way?
Thanks in advance
You can pipe all of your *.c files to the xgettext program using xargs assuming you're on Linux/Mac, e.g:
~$ find MyFolder -name "*.c \
| xargs xgettext --keyword=_ --language=C --output=messages.pot -
Be sure to pass - as the last parameter so it reads all files from stdin. Also you'll want to replace my simple keyword=_ example with the correct C function names.
From similar question in php, it is easy to know:
find . -iname "*.c" | xargs xgettext

Need a little help, I need correct syntax for grep and copy

I currently have 3TB of data on a disk with small to medium files in hundreds of folders.
I need to find certain text files witch contain certain words ( more than one word ).
I've already tried grep-ping for them.
This works as it prints the path to every file.
But this is a long list and I'm now looking for a workable way to copy them to another folder.
any ideas ?
Is there some way to put -exec cp -rv /estinationfolder in the syntax and have it copy all results to the folder ?
Yes , certainly there is a way.
You can pipe the grep output to copy command and provide required destination directory.
Here is a example,
find . -type f | xargs grep -l "textToSearch" | cpio -pV $destination_path
this script will copy files to destination path provided in destination_path variable
Best part with this is, it will copy the files while preserving the full path.

How can I extract all localizable strings from all XIB files into one file?

I am looking for a way of extracting all localizable strings from .xib files and have all of them saved in a single file.
Probably this involves ibtool but I was not able to determine a way of merging all these in only one translation dictionary (could be .strings, .plist or something else).
Open terminal and cd to the root directory of the project (or directory where you store all XIB files) and type in this command:
find . -name \*.xib | xargs -t -I '{}' ibtool --generate-strings-file '{}'.txt '{}'
The magic is the find and xargs commands working together. -I option generates placeholder. -t is just for verbose output (you see what commands has been generated and executed).
It generates txts files with the same name as xib files in the same directory.
This command can be improved to concatenate output into one file but still is a good starting point.
Joining them together:
You can concatenate those freshly created files into one using similar terminal command:
find . -name \*.xib.txt | xargs -t -I '{}' cat '{}' > ./xib-strings-concatenated.txt
This command will put all strings into one file xib-strings-concatenated.txt in root directory.
You can delete generated partial files (if you want) using find and xargs again:
find . -name \*.xib.txt | xargs -t -I '{}' rm -f '{}'
this is a lot easier now.
in xcode, select your project (not a target)
then use menu/editor/export for localisation
xcode will output an xliff file with all localisable strings from your entire project.

Resources