0

I would expect this to print the contents of foobar.txt:

echo "~/sandbox/foobar.txt" | cat

But instead it just prints to the console:

~/sandbox/foobar.txt

How can I cat the file contents instead of printing the filename?

EDIT: Here's a non-contrived example of what I'm actually trying to do:

echo $RESULT \
  | grep "check file .*make.err" \
  | sed -e "s/.*check file '//" \
  | sed -e "s/'.*//" \
  | xargs cat

EDIT 2: RESULT holds the output of a previous command in my script file. Here is what that might look like:

runspec v6152 - Copyright 1999-2008 Standard Performance Evaluation Corporation
Using 'macosx' tools
Reading MANIFEST... 18357 files
Loading runspec modules................
Locating benchmarks...found 31 benchmarks in 6 benchsets.
Reading config file '/Users/<REDACTED>/spec/installation/config/<REDACTED>.cfg'
Benchmarks selected: 400.perlbench
Compiling Binaries
  Building 400.perlbench base macosx-ia32-iccifortv101-pgofast-static default: (build_base_macosx-ia32-iccifortv101-pgofast-static.0000)
Error with make 'specmake build': check file '/Users/<REDACTED>/spec/installation/benchspec/CPU2006/400.perlbench/build/build_base_macosx-ia32-iccifortv101-pgofast-static.0000/make.err'
  Command returned exit code 2
  Error with make!
*** Error building 400.perlbench
If you wish to ignore this error, please use '-I' or ignore errors.

The log for this run is in /Users/<REDACTED>/spec/installation/result/CPU2006.062.log
The debug log for this run is in /Users/<REDACTED>/spec/installation/result/CPU2006.062.log.debug

*
* Temporary files were NOT deleted; keeping temporaries such as
* /Users/<REDACTED>/spec/installation/result/CPU2006.062.log.debug
* (These may be large!)
*
runspec finished at Sat Feb 21 08:40:02 2015; 15 total seconds elapsed
Daryl
  • 3,253
  • 4
  • 29
  • 39
  • 1
    Why do you need to do that? `cat ~/sandbox/foobar.txt` is better. Your example doesn't show why such a thing would be useful. – gniourf_gniourf Feb 21 '15 at 19:06
  • @gniourf_gniourf, does that clarify my intent? – Daryl Feb 21 '15 at 19:44
  • But it's sooooo ugly! I assume that your task is even more (seemingly) complex than that: you're parsing the output of a command and want to extract a string in there. If it's the case, could you please edit (once more!) your post to show the actual output of your command? (or a relevant portion of it if it's too long) – gniourf_gniourf Feb 21 '15 at 20:31
  • Otherwise, this would work (arguably better than `xargs`): `cat "$(echo "$RESULT" | grep "check file .*make.err" | sed -e "s/.*check file '//" | sed -e "s/'.*//")"`. – gniourf_gniourf Feb 21 '15 at 20:32
  • I don't want to offend you, but you very likely didn't understand the Unix philosophy completely. While it is true that part of the philosophy is to develop small and specialized tools that do one thing very well, this doesn't mean that each time you have a task to solve you need zillions of these tools chained together in pipes! on the contrary, these tools being so powerful and well designed, only one or two will be enough. In your example, when I see a pipe like `grep | sed | sed`, I think it's very likely possible to achieve the same with a unique `sed` or `awk` (or even in pure Bash!). – gniourf_gniourf Feb 21 '15 at 20:41
  • @gniourf_gniourf, no offense taken. I'm pretty new to Unix :) I'm 100% sure there is a more streamline way to do what I'm trying, but I've only learned a few tools with a few usages so far. – Daryl Feb 21 '15 at 20:47
  • 1
    Good `:)`. Please show a sample of the output your parsing! – gniourf_gniourf Feb 21 '15 at 21:01
  • @gniourf_gniourf Done. I'm very open to suggestions :) – Daryl Feb 21 '15 at 21:57
  • Whatever you do, **use more quotes.** You _definitely_ want: `echo "$RESULT"` **with the quotes `"` around `$RESULT`**. Without these quotes, newlines are not preserved (but that's a small detail), and (more importantly) your command is subject to pathname expansion! try, just for fun, to `echo $RESULT` (like so, without quotes) somewhere in your script. You'll see that it's an awful mess, and that all the wildcards `*` got expanded to the filenames of your current directory. Horror. – gniourf_gniourf Feb 21 '15 at 22:19

2 Answers2

3

To turn stdin into arguments, you can use xargs:

echo ~/sandbox/foobar.txt | xargs cat

To prevent issues with special characters (quotes and spaces), you can use xargs -0 and pass in \0 separated files:

printf "%s\0" ~/sandbox/foobar.txt | xargs -0 cat --

Note that you can't doublequoting the ~ like you did in your example. Replacing ~ with the user's home directory is the shell's job, and if you double quote it, you suppress this.

that other guy
  • 116,971
  • 11
  • 170
  • 194
-1

If you want the contents of foobar.txt:

cat ~/sandbox/foobar.txt

or:

cat `echo ~/sandbox/foobar.txt`

Which is equivalent (but overly complex)

If you want the contents of foobar.txt to be treated as filenames of files to be catted, you could use:

cat `cat ~/sandbox/foobar.txt`

The backticks make the results of the inner cat appear as arguments for the outer cat. LolCats!

wildplasser
  • 43,142
  • 8
  • 66
  • 109
  • Well,`cat \`cat ~/sandbox/foobar.txt\`` ? Really,you missed `echo` I guess! And also, it'll just print the lines all concatenated together. Give it a try,I did. – Am_I_Helpful Feb 21 '15 at 18:57
  • The foobar.txt contains filenames to be catted , doesn't it ? Did you try it? – wildplasser Feb 21 '15 at 18:58
  • Please read the question again,it seems you mis-judged it! I am telling about `echo \`cat ~/sandbox/foobar.txt\``. You should edit this! And,even this wouldn't do! No,it is simply to be printed. – Am_I_Helpful Feb 21 '15 at 19:00