Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

[flagged]


Reason why you would do that (and I often do) is that you have further piping options so it becomes standard work flow and muscle memory.

What I usually do is cat the file to inspect it, hit Control+C, then up arrow for previous command, then further pipe and head/tail/grep the file.

Starting a grep command is fine if you know that's all you're going to be doing.


You can use Bash (and I assumed it works in zsh too) variables to save you there. eg

    grep something !$
`!$` will be replaced with the last parameter of the previous command. Crude example

    cat /etc/hosts
    grep 12.34.56.78 $! # will be executed as grep 12.34.56.78 /etc/hosts
I find this extremely useful for when I'm cat'ing a file to get a sense of it's output then wanting to do something more meaningful with it in the next command.

That all said, I have absent-mindedly done my fair share of stuff like this too:

    !! | less
    # eg will run as `cat /etc/hosts | less`
    # if `cat /etc/hosts` was the previous command run
so I certainly wouldn't look down on people who have "abused" cat due to muscle memory.


You can also hit Alt-. to insert the last argument of the previous command.


Unfortunately not on Macs :(

That's one of the features I miss the most when using terminals on a Mac.


Of course you can. It’s «ESC .» or «^[.»

Or you can check “Profiles → Keyboard → Use Option as Meta” for Terminal.app [or just press ⌥⌘O]. And then use option as meta.


> Of course you can. It’s «ESC .» or «^[.»

Thanks, I wasn't aware of that. However it's a different hotkey and only pulls the last parameter. The shell I use, you could hit <alt>+<number> and you would get a parameter of that number completed - not just the last parameter. It was very handy for rebuilding long command lines with different arguments.

> Or you can check “Profiles → Keyboard → Use Option as Meta” for Terminal.app [or just press ⌥⌘O]. And then use option as meta.

I use iTerm2 - which does seem to have similar options but I'm yet to get it working. I know that's down to user error but it's still a real pity that it isn't just the default behaviour (in either iTerm or Terminal).


ctrl-meta-y (readline’s yank-nth-arg) pulls any argument.


Works fine here (Terminal.app + bash 5.0.3 from homebrew).

Also, isn't that special variable $_ and not $! ?


> Works fine here. Terminal.app + bash 5.0.3 from homebrew.?

Doesn't work for me. Maybe I've broken something on my build? Or maybe you've redefined your keys to emulate the [alt] key?

> Also, isn't that special variable $_ and not $! ?

Sorry I meant `!$` not `$!` (updated my post accordingly).

Yes, $_ does the same thing too.


Go to settings and enable "use option as meta key"


I just use M-. (meta+.⃣) for that (aka M-_ aka readline’s yank-last-arg)


that is correct, but this case is obviously different :-)


I do cat x | grep y, because that way you separate out the primary data being passed around and the secondary instructions for how to process it. Preferring functional programming, this is my bread and butter. It´s superior readability and simplicity is something that gets engraved on the inside of your mind after you do a pipe a few hundred times per day every day. This is not about being terse, terseness is almost never a factor.

  (->
  ¨log.txt¨
  read-to-string 
  ´(prepend ¨\n¨)
  ´(prepend ¨piping¨)
  lines-to-strings
  first
  ´(= ¨piping´)
  )
To think of writing (read-to-string ¨log.txt¨) in the above pipe is wrong. Might as well load on more functions on the input line:

  (->
  (prepend ¨piping¨ (prepend ¨\n¨ (read-to-string ¨log.txt¨)))
  lines-to-strings
  first
  ´(= ¨piping´)
  )
The simple principle that emerges is that the first line is for input, not for applying functions. You might guess that someone who does this even in a pipe as simple as cat x | grep y has this muscle memory too, but someone who criticizes it, certainly doesn´t. Maybe that´s not a bad thing, but you do feel a large divide between each other.


I'm fond of this bashism: `<myfile command | command | etc`


This is portable syntax, not a bashism.


As someone who doesn't care, my eyes bleed every time someone tries to make others feel small for no reason using improper grammar:

"As na linux/unix sysadmin": typo ('na') aside it is 'As a linux/unix sysadmin'

"...my eyes are bleeding everytime I see" I think you meant 'my eyes bleed', otherwise it means that, coincidentally, you eyes were already bleeding every time you happen to see someone use cat in that way.

"everytime" is wrong, the correct form is "every time"

My point isn't to insult you, it is to show you that everyone has blind spots and we shouldn't give each other such a hard time.


Grammar and spelling blind spots don't compromise the security of thousands of people. I think if you're going to make such glaring mistakes, you should be able to take a bit of guff for it.


> Grammar and spelling blind spots don't compromise the security of thousands of people

Neither does useless use of cat. Or am I missing something that I couldn't read because of a deleted comment?


No you're not, my mistake. Due to the parent comment being flagged, I incorrectly the response as a reply to different comment.


Haha, that escalated quickly ;)


There are several benefits to it. "cat filename" is a natural starting point for building pipelines interactively one step at a time. It puts the first input on the left side of the command that consumes it. (The alternative of "cmd1 [<]filename | cmd2 ..." does not quite read left-to-right, and some shells do not support "<filename cmd1 | cmd2 ..."; for example, fish doesn't.) When you are done with preliminary testing and want to run the pipeline on a larger amount of data "cat" is quicker to replace with "pv" (and vice versa). You do incur a performance cost with both "cat" and "pv". The command consuming the input also can't seek on it with "cat", but it doesn't matter if you are processing the input one record at a time. If you like the ergonomic benefits, use "cat" until you are optimizing for performance.


but but but... what about the single responsibility principle??? Grep can't both load the file and pattern match against it's contents! Sacrilege.


I know you're being facetious, but every utility is supposed to be able to open and read a FILE handle, even if it's just stdin.


Well technically you're not opening stdin. It's handed to you by your parent.


As a sysadmin with 20+ years of experience, I always type `cat | grep`, completely involuntary, probably because "cat = read" is just burned into me, by the time I think about it the command is already written. Also maybe related to catting more than grepping :D


I do it because it's easier than remembering grep's argument order.


More importantly, it is easier to remember how every tool expects the file argument. cat | foo always works.


Try this then, to hook up the file to grep's stdin directly.

    <filename grep foo


Neat!


Yeah, but there are several reasons

1 - you want to add more filtering/processing before the grep

2 - grep's command line options are confusing (+ globbing + whatever), easier to just use it to grep stdin

3 - It works. Sure 'grep pattern file' works, but here that is inconsequential. I'm not in an 80s machine to worry if I'm opening one more process or pipe than needed, especially in simple cases like this


I have no issue with people who want to prefix grep (nor any other command for that matter) with cat. However I do completely disagree with your 2nd point. It's literally just:

    grep  [flags]  search_pattern  [filename]
In GNU grep (eg Linux) it's even easier because your flags can appear wherever in the command you want (even at the end). Though I'd recommend sticking to the habit of having them after the executable name for readability and portability with non-GNU coreutils.

It's really not that hard. There's plenty worse CLI tools to use which we're now stuck with because of historic reasons.


It's easy, once you get it

Take a look at the man page (linux)

    grep [OPTIONS] PATTERN [FILE...]

    grep [OPTIONS] -e PATTERN ... [FILE...]

    grep [OPTIONS] -f FILE ... [FILE...]
Now -f does not specify the file to grep, it specifies a file where to read patterns from (and they have the same "variable" name there, confusing)

Not to mention globbing and other shell escapes (which is not grep's fault, of course, but you might end up hitting in some situations)


That's not a typical usage of grep and nor is it even the first instruction in the man page.

Let's actually take a look at the man page shall we:

    Synopsis
    
    grep [OPTIONS] PATTERN [FILE...]
    grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
That first line is more or less exactly what I posted, is your typical usage of grep, and is very easy to learn.

Sure, you can list of esoteric examples of grep usage but that's besides the point if it's not how people would typically use grep (in my ~25 years of command line usage, I can't even remember one occasion when I've needed `-f` - not saying it hasn't happened but it certainly isn't something I've needed regularly)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: