0

How do I display content of files with name containing letter 'a' in it? I tried cat|ls|grep 'a'

1
  • 4
    Do you mean files that would match the glob pattern *a*? Commented Jan 25, 2018 at 20:07

5 Answers 5

4

This should work:

find . -type f -name '*a*' -exec cat {} \; 
2
  • In some situations, the shell will need elements of your answer escaped, specifically the end of the find command may need to be '{}' \+ Commented Jan 26, 2018 at 10:12
  • 2
    @user1404316, + is not special in any shell. {} is not special in any shell of the Bourne or csh families. It's special in rc/es/fish. But then if we have to cover for those shells many answers here would not work either as for instance % is also special in fish and " is not a quoting operator in rc/es. And backslash is not a quoting operator in rc either, so your \+ wouldn't work there. When the shell is not specified, POSIX sh or compatible is usually implied here. Commented Jan 26, 2018 at 10:43
2

The less pager has a feature that allows browsing multiple files and jumping among them, so if all files are in the same directory less *a* will initially open the first, and you can at any time advance to the next file by typing :n or return to the previous file by typing :p. Typing = at any time will display the current file's name. The less pager has many other useful documented yet un-commonly used features. From within the program, type h for a long mutliple-page cheat sheet.

find -type f -maxdepth 1 -name '*a*' -exec less '{}' + 
1
  • 1
    It would be better to call less from -exec to support filenames that contains spaces. Commented Jan 26, 2018 at 9:35
1

If all files are located in the same directory, this short version will do it:

cat *a* 

In case of funny filenames starting with '-' a './' should be prefix:

cat ./*a* 

Directories with a will result in a non harmful error message.

4
  • That'll also try to cat non-files (directories, for example). Commented Jan 26, 2018 at 8:43
  • @Kusalananda, a directory is one many different types of files. Of all the different types of files, it's probably the one (along with sockets) that you're least likely to want to cat, but you may still want to cat devices or fifos or symlinks to regular files (all of which would be excluded by find -type f or zsh's cat ./*(.)) depending on context. Commented Jan 26, 2018 at 9:53
  • It would fail for file names starting with - though. You may prefer cat ./*a* or cat -- *a* Commented Jan 26, 2018 at 9:54
  • @StéphaneChazelas ./ is good. I've added it. Commented Jan 28, 2018 at 8:00
0

If the files are located in one directory you can use

for i in *a*; do ( echo $i && cat $i && echo " "); done

to show all the files. Nevertheless you are still able to remember which output comes from which file and there is a seperation of the individual file output.

2
  • 1
    What's the subshell for? Commented Jan 26, 2018 at 8:53
  • There may be things that are not regularly files that matches that pattern. You also need to double quote the variable expansions to support multi-word names. Commented Jan 26, 2018 at 9:34
0

To output the content of all regular files in the current directory whose name contains the a character:

find . ! -name . -prune -name '*a*' -type f -exec cat {} + 

Though with several find implementations (including the GNU one on your Ubuntu), that would exclude files whose name contains byte sequences that don't form valid characters in the current locale.

With some find implementations, you can use -depth 1 instead of the standard ! -name . -prune. Some others (like GNU find) have -mindepth 1 -maxdepth 1 (though -maxdepth 1 is enough here as depth 0 is . which is excluded by both -type f and -name '*a*').

The invalid character issue could be alleviated by using zsh and:

cat ./*a*(D.) 

Which would also have the benefit of reporting an error if there's no matching file and sorting the list of files so the output is less random.

If you also want to include symlinks to regular files, add a -L option to find or - in the zsh glob qualifier.

If you want to exclude hidden files, add a ! -name '.*' to find or remove the D from zsh's glob qualifier.

Note that cat concatenates those files. If a1 contains foo without a trailing newline character (which shouldn't happen if a1 were a proper text file) and a2 contained bar, the output would be foobar.

To include the file names, you could use grep '^' /dev/null instead of cat which would prepend each line with the name of the file. Or grep -n '^' /dev/null to also include line numbers.

With the GNU implementation of head (as found on your Ubuntu), you can use head -vc-0 which would add a

===> ./file_with_a <=== 

header and an empty line between each file.

2
  • In some situations, the shell will need elements of your answer escaped, specifically the end of the find command may need to be '{}' \+ Commented Jan 26, 2018 at 10:10
  • @user1404316, + is not special in any shell. {} is not special in any shell of the Bourne or csh families. It's special in rc/es/fish. But then if we have to cover for those shells many answers there would not work either as for instance % is also special in fish and " is not a quoting operator in rc/es. And backslash is not a quoting operator in rc either, so your \+ wouldn't work there. When the shell is not specified, POSIX sh or compatible is usually implied here. Commented Jan 26, 2018 at 10:28

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.