11

In my coding, I always do grep -rnIi "abcabc" . --color

But, how to make an alias that can let me type only one word with my search string? Is that possible?

Braiam
  • 35,991
BufBills
  • 3,095
  • Genuinely curious: what coding are you doing with an alias? I was under the impression they were mostly deprecated and, despite a few days of fervent hacking at oblique possibilities, I could never make them very useful because in almost all script worthy scenarios the shell refused to parse them. Eventually I settled on some compromise involving functions and heredocs that provided something like python's burner lambdas but I sure would prefer aliases... – mikeserv Mar 04 '14 at 02:44
  • @mikeserv I think the OP meant while coding as opposed to in the actual code. – terdon Mar 04 '14 at 03:20
  • Bummer. They sure are fast. – mikeserv Mar 04 '14 at 03:50

2 Answers2

15

Pay attention to the tags on this question. This answer is the correct one given the version of grep that's included with CentOS 6 is below version 2.11

I don't believe you can do this using just an alias (at least not in the form that you've written it - see @Graeme's answer for an alternative syntax).

NOTE: I'll also mention here that @Graeme's solution though correct does not work on CentOS 5 & 6. I've confirmed this and it does in fact appear to be an issue with the version of grep (2.11 or older) that's bundled with those distros. The issue appears to be with grep not, by default, searching STDIN when no path argument is provided with the -r switch. Running grep -rnIi --color "string" just hangs indefinitely, attempting to search STDIN.

Aliases cannot take arguments being passed into them. They're more synonymous to a macro where they can get expanded by the shell to something else.

$ alias ll='ls -l'

This can then be used like so:

$ ll
-or-
$ ll somedir

But somedir isn't passed to ll, rather ll is expanded in place to ls -l and then replaces ll in your command.

Back to your question

You can use a function in the shell instead. Functions can take arguments.

$ function mygrep { grep -rnIi "$1" . --color; }

You then use it like this:

$ mygrep "blah"

    ss of ex

slm
  • 369,824
  • "The issue appears to be with grep not, be default, searching the current directory when provided the -r switch." Having a little trouble parsing that. – Faheem Mitha Mar 04 '14 at 04:28
  • @FaheemMitha - is that better? – slm Mar 04 '14 at 06:29
  • slm: please see my comment on Graeme's answer. You can not assume grep will use the current dir as a default. grep (should) need both a string and "a place where to look for it". Its default is not "current dir", but "Standard Input", so your tries (Running grep -rnIi --color "string" just hangs indefinitely, waiting for a file/path argument to search) was in fact not waiting for a file/path, but was already grepping the standard input. Graeme's mygrep 'abcabc' . should work fine on CentOS as on any other "normal" unixes (using bash/sh/many others). – Olivier Dulac Mar 04 '14 at 08:13
  • @slm, you are right, it is the version. Previous behaviour was to ignore the -r, so it would just match from stdin as usual. – Graeme Mar 04 '14 at 11:07
  • @OlivierDulac - OK, so I didn't quite explain it correctly but the issue still remains with grep on CentOS due to the dated version of grep that's included. Yes, I'm aware that the grep '...' . will work, it's just that you cannot do that as an alias, so the function method is the correct solution given the tags set on this particular Q. – slm Mar 04 '14 at 12:35
  • @slm: with alias mygrep='grep -rnIi --color' : when you then mygrep "something" somewhere it will expand to grep -rnIi --color "something" somewhere (and therefore will work as expected). you can have as many arguments after "mygrep" as you want: the first one will be the regexp to look for, the next one(s) will be places to look at/in. (as the alias only expands to "grep -options", the rest of the line will be appended to it by the shell) – Olivier Dulac Mar 04 '14 at 14:47
  • @OlivierDulac - yes I understand that but read the original Q: "alias that can let me type only one word with my search string". He only wanted to have to type 1 word, so the OP obviously didn't understand that you cannot pass arguments in the same sense that one would pass arguments to a function. I understand you can be smart and intelligently construct aliases in savvy ways but given his requirement, and the issue with grep + -r it wasn't feasible to do it, hence my A. – slm Mar 04 '14 at 15:47
  • @slm: ah, indeed, with that (impossible) requirement I agree. (I focused on the question's title, "make grep command shorter" ^^) – Olivier Dulac Mar 04 '14 at 16:51
  • @OlivierDulac - yes I figured as much, there was much confusion about this in the chatroom too. – slm Mar 04 '14 at 17:01
11

This can actually be an alias. The --color doesn't have to be at the end, and grep always searches the current directory with -r if no directory option is given (at least GNU grep does). Therefore you can do:

alias mygrep='grep -rnIi --color'

Update

The behaviour of searching the current directory by default was introduced in GNU grep 2.11. From the changelog:

If no file operand is given, and a command-line -r or equivalent option is given, grep now searches the working directory. Formerly grep ignored the -r and searched standard input nonrecursively. An -r found in GREP_OPTIONS does not have this new effect.

So, on versions >=2.11 of GNU grep, usage of the alias would be as follows:

mygrep PATTERN [PATH...]

For versions of grep before this, you would have to specify the path every time @slm's answer using a function is the best way. Although you could achieve the same usage as above by writing the function like this:

mygrep () { grep -rnIi --color "$1" "${2:-.}"; }

Assuming, of course, that there is no requirement for the --color to be at the end as in the Q...

Graeme
  • 34,027
  • actually it works on ubuntu but not Redhat enterprise – BufBills Mar 04 '14 at 02:15
  • 1
    That must be due to an older version of grep, I just tried it on Fedora 19 and it worked fine. I've confirmed that it def. doesn't work on CentOS 5 or 6. CentOS 6 = 2.6.3, Fedora 19 = 2.14. – slm Mar 04 '14 at 02:41
  • I've incorporated this issue into my A just so others aren't confused as to why my A is accepted and higher voted, since you're approach would be the more normal course 8-). – slm Mar 04 '14 at 02:49
  • 1
    I believe your solution is the easiest and so "more correct" one. But you need to show how it's used: mygrep something somewhere (ex: mygrep "abcabc" . , for the OP's example). Grep needs both something to search for, and where to search it (a file, or a directory, both are valid here). The alias only provides the options, as those can (and should) be placed before the arguments. – Olivier Dulac Mar 04 '14 at 08:10
  • Otherwise, with no "place" to search in, it greps the standard input. – Olivier Dulac Mar 04 '14 at 08:15
  • @Oliver, it definitely looks in the current directory for me. I use this behaviour regularly! grep (GNU grep) 2.16 – Graeme Mar 04 '14 at 10:16
  • @NoName, updated, the alias works for version 2.11 and upward – Graeme Mar 04 '14 at 11:10
  • @OlivierDulac - It's not possible to make an alias with arguments sandwiched in between. Without being able to exploit the feature of grep in searching the current directory with the -r switch, this solution won't work on CentOS 6 + it's def. version of grep. – slm Mar 04 '14 at 12:43