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.

From the command line, what is the easiest way to show the contents of multiple files? My directory looks like below.

./WtCgikkCFHmmuXQXp0FkZjVrnJSU64Jb9WSyZ52b
./xdIwVHnHY7dnuM9zcPDYQGZFdoVORPyMVD2IzjgM
./GZnATXO1e5Hh3Bz1bhgJjjwheIjjZqtnXR0hfOyj
./mWz7ehBNoTZmtDh8JG6sxw2lMJFwIovPzxDGECUY
./JN65F5v3RL2ilHPqNSx9N9D4lvVpqpbJ9lASd8TJ
./At9PS4y4nTiXUO0Z0USnbYkTPBla1msQRpwuruqE
./YiPyMZPCaUDZTiTczAvWII9bJrUqLXCFtH2pXEA2
./JoakdlbRFPwAvWp1d4n8RvMoyMeizCoiriL2Sn2U
./wFPWZUus8Yu7UtESGABLCoqDg36cT90USO0xuyUr
./qseI9PgV1EJfZCDyGGeVytajqG7JeX0r7eA5S1JW
./zgFJpNgXyCsaVh38aCuMGuzHwIbwSNB6rQDdh27x
./.htaccess

Now I'd like to view the contents of all files except .htaccess. It might look something like:

WtCgikkCFHmmuXQXp0FkZjVrnJSU64Jb9WSyZ52b:
Contents of file WtCgikkCFHmmuXQXp0FkZjVrnJSU64Jb9WSyZ52b.

xdIwVHnHY7dnuM9zcPDYQGZFdoVORPyMVD2IzjgM:
Contents of file xdIwVHnHY7dnuM9zcPDYQGZFdoVORPyMVD2IzjgM.

[...]

I think this should be doable with a combination of find, xargs and cat, but I haven't figured out how. Thanks for your time!

share|improve this question
add comment

3 Answers

up vote 7 down vote accepted

The two standard commands head and tail print a header with the file name if you pass them more than one file argument. To print the whole file, use tail -n +1 (print from the first line onwards, i.e. everything).

Here, it looks like you want to see every file except the single one whose name begins with a dot. Dot files are “hidden” under unix: they don't appear in the default output of ls or in a wildcard match. So matching every non-hidden files is done with just *.

tail -n +1 *

(Strictly speaking, tail -n +1 -- * is needed in case one of the file names begins with a -.)

share|improve this answer
    
Short and sweet, thank you! Do you know where I can read about the -- modifier? –  Znarkus Apr 30 '11 at 10:37
2  
@Znarkus: -- to signify the end of options is a convention that most commands obey. E.g. tail -n +1 -- -f -g tells tail that -f and -g are files to read (operands) and not options. It's guideline 10 in the POSIX utility syntax guideline (a document intended for utility writers). I don't have a reading suggestion intended for end-users, I'd expect a good unix tutorial to cover it at some point. –  Gilles Apr 30 '11 at 10:50
add comment

You can do it all in one with find:

$ find . -type f -not -name .htaccess -printf "\n%p\n" -exec cat {} \;

That tells find to find all files (-type f) in the current directory (.) except (-not) one named .htaccess (-name .htaccess). Then it prints (-printf) a newline followed by the filename (%p), and then runs cat on the file (-exec cat {} \;). That will give you output like:

test/test3
Line 1

test/test2
Line 1

test/test1
Line 1
Line 2
Line 3

If you do this often it might be worth sticking it in a shell script or a function; I have one named cats that does exactly that:

#!/bin/bash
for filename; do
    echo "\033[32;1m$filename\033[0m"
    cat "$filename"
    echo
done

It loops over each filename argument, prints out the filename (in bold green), and then cats the file:

Example screenshot

So then the command would just be:

$ find . -type f -not -name .htaccess -exec cats {} \+
share|improve this answer
    
The other was shorter, so accepted that. Excellent answer though, thank you! –  Znarkus Apr 30 '11 at 10:37
add comment

If you want to fine tune and don't loose too much time with pipes, find and everything (altough being the most powerful toolchain you could ever find)

just try to use a for-loop, cat, etc.

share|improve this answer
add comment

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.