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*?
    – dhag
    Jan 25 '18 at 20:07
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 '{}' \+ Jan 26 '18 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. Jan 26 '18 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.
    – Kusalananda
    Jan 26 '18 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).
    – Kusalananda
    Jan 26 '18 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. Jan 26 '18 at 9:53
  • It would fail for file names starting with - though. You may prefer cat ./*a* or cat -- *a* Jan 26 '18 at 9:54
  • @StéphaneChazelas ./ is good. I've added it.
    – hschou
    Jan 28 '18 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?
    – user147505
    Jan 26 '18 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.
    – Kusalananda
    Jan 26 '18 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 '{}' \+ Jan 26 '18 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. Jan 26 '18 at 10:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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