Live data from Hacker News

PSA about abuse of cat(1) command. Don't abuse cats

abuseofcats.com

41–50 of 62 posts

Re: PSA about abuse of cat(1) command. Don't abuse cats

#41
post #3

> Since 1995, occasional awards for UUOC have been given out, usually by Perl luminary Randal L. Schwartz http://catb.org/jargon/html/U/UUOC.html Admittedly its taken me a long time to remember that the file is the last argument to grep, when so many other commands its the first. I'd guess common abuse is due to being easier to type cat x | than to dig up the man page

And also typing cat x to get a quick look at the file, hitting up, then piping that into another command and taking a look, hitting up, piping that result into a third command etc.

I suppose a lot of people use less rather than cat for looking at files though.

`alt + .` is much more versatile. You can use it to cycle through and insert the last arguments of previous commands.

Re: PSA about abuse of cat(1) command. Don't abuse cats

#42
post #33

The beauty of cat is that streams are the universal interface. Program A might accept a file as the last positional arg. Program B might accept it as a named arg, where the name/flag could be anything from --input or -f or --file etc. But a program will read from STDIN, which all good unix programs do, then piping cat into it works every time. I can write the cat foo.txt part before I even know what command I'm pipin…

This. Sometimes I want to see what I'm looking at and then (using that dump as a reference) follow up with a corresponding filter (| jq .key, or | tail -n 30). Sure, I could use less, but then I context switch on exit; no support from the scrollback buffer. I've probably lost 10ms * 1E5 of my life from the extra PID. But, probably would lose more in the context switch.

alias less=‘less -X’

Re: PSA about abuse of cat(1) command. Don't abuse cats

#43
post #33

The beauty of cat is that streams are the universal interface. Program A might accept a file as the last positional arg. Program B might accept it as a named arg, where the name/flag could be anything from --input or -f or --file etc. But a program will read from STDIN, which all good unix programs do, then piping cat into it works every time. I can write the cat foo.txt part before I even know what command I'm pipin…

This. Sometimes I want to see what I'm looking at and then (using that dump as a reference) follow up with a corresponding filter (| jq .key, or | tail -n 30). Sure, I could use less, but then I context switch on exit; no support from the scrollback buffer. I've probably lost 10ms * 1E5 of my life from the extra PID. But, probably would lose more in the context switch.

I'm never doing just one thing to a file! I'm grepping and JQing and then piping it to JQ again because I'm kind of dumb (and it's faster to do what I do know how to do than it is to look up the perfect way to do it), then I'm outputting as a TSV and piping that to `column -ts $'\t'`. ^r reveals a decent example:

    cat expected.1376| sed '1,4d' | rg '(\t\d)\t.*' --replace '$1' | column -ts $'\t'
I was figuring shit out along the way and it'd be pretty annoying to adjust which command gets the filename throughout that process.

You know what? I'll tell you another thing I do that's similar:

    SELECT * FROM whatever WHERE true
        AND last_modified > 123
        AND otherfield NOT NULL
Always bugged me that you say WHERE for the first one and AND thereafter, so if I'm poking around the database trying to create actionable insights for key stakeholders at the speed of business just as I was above with the text file, I like to be able to futz and delete/add clauses as I see fit just as I do pipeline stages.

Re: PSA about abuse of cat(1) command. Don't abuse cats

#44
post #19

Don't do this: cat file | wc -l => wc -l head -n 5 file cat file | awk '{print $1}' => awk '{print $1}' file cat file | sort => sort file Do this instead: cat file | wc -l => The front-cat abuse is all about the order. The effective solution needs to keep the relative order of arguments.

Or just use cat and spend your brainpower on interesting, useful, and/or worthwhile topics. It boggles my mind that anyone cares about this.

If one needs brainpower to just use the redirection operator, it shows a likely lack of understanding of basic concepts in computing like processes and files. That should be concerning.

Re: PSA about abuse of cat(1) command. Don't abuse cats

#45

[flagged]

Chances are the file stays the same and what Im grepping for changes, so after the first run, it was less work for me not needing to go back as far in the command cat file | grep thingone cat file | grep thingtwo Vs grep thingone file grep thingtwo file

If it really matters to you that much then `<file grep thing` has the desired order and is less to type out.

Re: PSA about abuse of cat(1) command. Don't abuse cats

#46
post #20

if this wanton abuse of cat(1) doesn't stop, we're on track to run out of PIDs by 2031! Just because Unix makes it cheap and easy to fork doesn't mean you have to! (who gives even a single shit, my god)

Is this a dig at IPv6?

Definitely not, I like IPv6.

Re: PSA about abuse of cat(1) command. Don't abuse cats

#47
For interactive use like these examples I think this is terrible advice. cat is very helpful because it fits into pipelines like every other command. For example:

Take a look at the start of a file:

  head file
Filter for things:

  head file | grep ... 
Reformat, remove unwanted stuff, etc.:

  head file | grep ... | sed ...
Do things or dry run echo based on each line:

  head file | grep ... | sed ... | while read a; do ...; done
It all looks good so we change head to cat to run it on the whole file:

  cat file | grep ... | sed ... | while read a; do... ; done
Yes you can technically change "head file |" to " cat.

Same is true for other workflows. E.g. if you start with one of these supposedly better commands like "wc -l

  wc -l 
Oh wait, we don't want every line, just ones matching a pattern. We could change it to

  wc -l 
or

  grep -c ... file
which are both more work than just adding to an existing cat-based pipeline, where we just replace cat with "grep ...":

  grep ... file | wc -l
If we need to also match another pattern or whatever this pipeline approach is better then too.

Re: PSA about abuse of cat(1) command. Don't abuse cats

#48

Don't do this: cat file | wc -l => wc -l head -n 5 file cat file | awk '{print $1}' => awk '{print $1}' file cat file | sort => sort file Do this instead: cat file | wc -l => The front-cat abuse is all about the order. The effective solution needs to keep the relative order of arguments.

The order is the main thing, but it's not just that. It's common to swap cat with something else like head, tail, grep etc., and that's easy. If you have "< file command" instead of "cat file | command" you have to make edits in two places to insert the "|".

Re: PSA about abuse of cat(1) command. Don't abuse cats

#49
First off, stop using cat, use something modern. I recommend redpanda, rp, but I'm biased since I'm the author.

Anyway, the reason I use useless cat is because when I'm working with large files, it starts with head, not cat, or tail, and then only after I've built the pipeline do I use cat to process the whole file.

Re: PSA about abuse of cat(1) command. Don't abuse cats

#50
post #33

The beauty of cat is that streams are the universal interface. Program A might accept a file as the last positional arg. Program B might accept it as a named arg, where the name/flag could be anything from --input or -f or --file etc. But a program will read from STDIN, which all good unix programs do, then piping cat into it works every time. I can write the cat foo.txt part before I even know what command I'm pipin…

Yes, but "cat" is superfluous anyway.

You can start your pipeline with a file redirection: " output_file".

Post reply on HN