0

Greetings Stack Exchange,

My Goal:Execute ls to search the entire directory structure and grep to search for cats.py. Use cat to read the file cats.py. I know that sounds like Gnu/Linux inception.

I currently am new to bash and not really familiar with Stack Exchange so forgive me if this formatted terribly.

I execute the following ls -R -l -t -r | grep cats this returns the following

rw-r--r-- 1 user user 2179 Mar 18 08:53 cats.py

I have tried to use cat to read the file returned above, but I am having issues with how to assign the placeholder for the results of the grep command this is what I have tried and the results.

ls -R -l -t -r | grep cats | cat cats.py
cat: cats.py: No such file or directory

I believe the issues is the way I am executing the cat function should this look something like :

ls -R -l -t -r | grep cats | cat '{}'

or

ls -R -l -t -r | grep cats && cat cats.py
ctrl-alt-delor
  • 27,473
  • 9
  • 58
  • 102
  • 1
    You may need to study the linux shell some more, especially concerning the "CWD", ie. the Current Working Directory. When you have found the file, you should specify the full path or put yourself in that directory with "cd", before executing the "cat" command. – Gerard H. Pille Mar 25 '20 at 11:26
  • 2
    Also, [you should not parse `ls`](https://unix.stackexchange.com/questions/128985/why-not-parse-ls-and-what-to-do-instead) – pLumo Mar 25 '20 at 11:39

4 Answers4

4

The find command would be more appropriate:

find . -name 'cats.py' -exec cat {} \;
Gerard H. Pille
  • 2,350
  • 9
  • 13
  • That worked perfectly exactly what I was trying to accomplish Thank you very much – patrick gray Mar 25 '20 at 11:26
  • 1
    Why not `-exec ... +` ? Should have the same output. – pLumo Mar 25 '20 at 11:43
  • @pLumo why though? The `+` is to run fewer commands, but there's no benefit here. First because `cat` will print everything sequentially anyway and because we have no reason to expect multiple files. – terdon Mar 25 '20 at 12:13
  • @terdon in order to inform people about this feature. This feature is from 1989 and many people from the GNU universe don't know it yet as it has been ignored by `gfind` until recently. – schily Mar 25 '20 at 12:29
  • Ah, that's my excuse: when I learned unix the feature wasn't there yet! – Gerard H. Pille Mar 25 '20 at 12:37
  • If there is only one cats.py it doesn't make a difference of course... But I don't really see that information from the question and then I rather call `cat` once. Habits ... ;-) – pLumo Mar 25 '20 at 13:58
2

Use the find command. It can find the file, and run a command on it. ls has problems, especially if the -l option is given, as then you have a lot more data than you need (file-mode, date, owner, ... ).

i.e. (substitute the bits in the «»)

find «directory» -name '«file-name-glob-pattern»' -exec «command» {} \;

e.g.

find . -name 'cats.py' -exec cat {} \;

ctrl-alt-delor
  • 27,473
  • 9
  • 58
  • 102
  • Thank you for the information and the edit you Ladies and Gentlemen are the reason I enjoy learning new things. You answered the next question I was going to ask. – patrick gray Mar 25 '20 at 11:32
0

Alternative to find -exec, use extended globbing:

shopt -s extglob
cat **/cats.py

Optional: unset extglob option:

shopt -u extglob

Note, that this is similar to -exec cat {} + instead of -exec cat {} \;

The first runs:

cat file1 file2 file3

The latter runs:

cat file1
cat file2
cat file3

For this example, the output is the same but the first will run faster.

pLumo
  • 22,231
  • 2
  • 41
  • 66
0

This isn't pretty but seems to do what you requested.

cat `sudo ls -R -l -t -r | grep cats | awk '{print $9}'`

cat `sudo ls -R -l -t -r | grep `Local\ State` | awk '{print $9}'`
Czar
  • 179
  • 2