Adrian Adrian - 4 months ago 19x
Bash Question

bash not parsing (cat + grep) correctly

I have a text file


grep -P -e "^<job.+type.+rule" "Emake-4agents-1st-10-25-51.53.xml"

To make my grepping go faster, I do the following in

cat 1.grep | bash >

This works fine normally but in this case, I get the following:

$ cat 1.grep
grep -P -e "^<job.+type.+rule" "Emake-4agents-1st-10-25-51.53.xml"

$ cat 1.grep | bash >
: No such file or directory25-51.53.xml

Why does
think that my
filename is a directory?


The immediate problem is that the file 1.grep is in DOS/Windows format, and has a carriage return followed by linefeed at the end of the line. Windows treats that two-character combination as the end-of-line marker, but unix tools like bash (and grep and ...) will treat just the linefeed as the end-of-line marker, so the carriage return is treated as part of the line. As a result, it's trying to read from a file named "Emake-4agents-1st-10-25-51.53.xml^M" (where ^M indicates the carriage return), which doesn't exist, so it prints an error message with a carriage return in the middle of it:

cat: Emake-4agents-1st-10-25-51.53.xml^M
: No such file or directory

...where the carriage return makes the second part overwrite the first part, giving the cryptic result you saw.

Solution: use something like dos2unix to convert the file to unix (line-feed-only) format, and use text editors that store in the unix format.

However, I also have to agree with several comments that said using cat | bash is ... just plain weird. I'm not sure exactly what you're trying to accomplish in the bigger picture, but I can't think of any situation where that'd be the "right" way to do it.