Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there a command to show the directory/file name when cat files?

For example: assume two files f1.txt and f2.txt are under ./tmp

./tmp/f1.txt
./tmp/f2.txt 

Then when I do cat ./tmp/*.txt, only the content of files will be shown. But how to firstly show the file name, then the content?, e.g.:

 (The needed command):
 ./tmp/f1.txt:  
 This is from f1.txt
 and so on
 ./tmp/f1.txt:
 This is from f2.txt ...

Is there a command to do it? (There seems to be no option for 'cat' to show the file names)

share|improve this question

migrated from stackoverflow.com Aug 28 '12 at 16:23

This question came from our site for professional and enthusiast programmers.

    
Why was this downvoted? –  Bot Aug 28 '12 at 15:45
2  
Probably down-voted because it's more of a superuser.com question than a programming question. –  Paul R Aug 28 '12 at 15:47
1  
See also Cat with Headers and Line Numbers? –  Gilles Aug 28 '12 at 23:45
add comment

6 Answers 6

up vote 2 down vote accepted
$ for file in ./tmp/*.txt; do echo "$file";  cat "$file"; done

-or-

$ find ./tmp -maxdepth 1 -name "*.txt" -print -exec cat {} \;
share|improve this answer
1  
The first example will break on files that have spaces. You should never try to parse or iterate over the output of ls: mywiki.wooledge.org/ParsingLs –  jordanm Aug 28 '12 at 18:48
add comment

Just as another idea, try tail -n +1 ./tmp/*.txt

==> file1.txt <==
<contents of file1.txt>

==> file2.txt <==
<contents of file2.txt>

==> file3.txt <==
<contents of file3.txt>
share|improve this answer
add comment

You could easily write a tiny script doing just that,

for f in "$@" do; echo "This is from $f"; cat -- "$f"; done
share|improve this answer
    
Thanks, but is there a way to avoid using script - by using a command? –  lukmac Aug 28 '12 at 15:49
    
To my knowledge, there is not such a command –  juampa Aug 28 '12 at 15:52
    
What is the practical difference between a script and a command, or, why does it matter that multiple commands are entered on a single command-line to solve the problem? The command doesn't have to be in a file. You can run the "script" by just typing in the text given. –  kbulgrien Aug 28 '12 at 15:59
    
That is true - but i want to use something existed, please see the answer from "ire_and_curses" and "kbulgrien" –  lukmac Aug 28 '12 at 16:14
3  
Please use "$@" instead of $*, as the former will handle filenames with spaces (this is part of POSIX shell, it's not a bash-ism). Also, cat "$f". –  derobert Aug 28 '12 at 16:37
show 2 more comments
find . -name '*' -execdir cat '{}' \;

When a directory is passed to cat, you'll see something like:

cat: ./chapter_01: Is a directory

Immediately following, the find will cat the contents of that directory.

share|improve this answer
add comment

Not exactly what you asked for, but you can prefix each line with the filename:

$ grep ^ ./tmp/*.txt
./tmp/f1.txt: this is from f1.txt
./tmp/f1.txt: blaa, blaa, blaa...
./tmp/f1.txt: blaa, blaa, blaa...
./tmp/f2.txt: this is from f2.txt
./tmp/f2.txt: blaa, blaa, blaa...
./tmp/f2.txt: blaa, blaa, blaa...

It will be tough to do much better than this without resorting to a little scripting.

share|improve this answer
1  
That is a good workaround - my files are actually single line. –  lukmac Aug 28 '12 at 16:19
add comment

cat is (intentionally) an extremely simple command that just reads one file stream and dumps it to another (with a few basic formatting options). It'd be fairly easy to create a utility based on cat that did provide the filename, but standard versions won't do this -- probably because it's easy to replicate with other commands.

If you want to examine the pages manually you could use 'less'. This will give you the filename at the end of every file, in the format: 'foo.txt (file 1 of 100) (END) - Next: bar.txt).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.