10

I have thousands of unl files named something like this cbs_cdr_vou_20180624_603_126_239457.unl. I wanted to print all the lines from those files by using following command. but its giving me only file names. I don't need file names, I just need contents from those files.

find -type f -name 'cbs_cdr_vou_20180615*.unl'  > /home/fifa/cbs/test.txt

Current Output:

./cbs_cdr_vou_20180615_603_129_152023.unl
./cbs_cdr_vou_20180615_603_128_219001.unl
./cbs_cdr_vou_20180615_602_113_215712.unl
./cbs_cdr_vou_20180615_602_120_160466.unl
./cbs_cdr_vou_20180615_603_125_174428.unl
./cbs_cdr_vou_20180615_601_101_152369.unl
./cbs_cdr_vou_20180615_603_133_193306.unl

Expected output:

8801865252020|200200|20180613100325|;
8801837463298|200200|20180613111209|;
8801845136955|200200|20180613133708|;
8801845205889|200200|20180613141140|;
8801837612072|200200|20180613141525|;
8801877103875|200200|20180613183008|;
8801877167964|200200|20180613191607|;
8801845437651|200200|20180613200415|;
8801845437651|200200|20180613221625|;
8801839460670|200200|20180613235936|;

Please note that, for cat command I'm getting error like -bash: /bin/logger: Argument list too long that's why wanted to use find instead of cat command.

2
  • You still need to use cat. Jun 24, 2018 at 12:40
  • Yes! Can you please tell me how can I do that? @IgnacioVazquez-Abrams
    – Rezuan
    Jun 24, 2018 at 12:41

2 Answers 2

28

The find utility deals with pathnames. If no specific action is mentioned in the find command for the found pathnames, the default action is to output them.

You may perform an action on the found pathnames, such as running cat, by adding -exec to the find command:

find . -type f -name 'cbs_cdr_vou_20180615*.unl' -exec cat {} + >/home/fifa/cbs/test.txt

This would find all regular files in or under the current directory, whose names match the given pattern. For as large batches of these as possible, cat would be called to concatenate the contents of the files.

The output would go to /home/fifa/cbs/test.txt.

Related:

1
  • 1
    Working as expected and execution time is very fast which is really great. Many thanks.
    – Rezuan
    Jun 24, 2018 at 13:02
12

The output of find will result with the relevant file names.
You can pipe (|) the output to xargs cat which will perform the cat command on each file.

e.g.:

find -type f -name 'cbs_cdr_vou_20180615*.unl' | xargs cat  > /home/fifa/cbs/test.txt

Another option will be to use -exec cat

find -type f -name 'cbs_cdr_vou_20180615*.unl'  -exec cat {} \;  > /home/fifa/cbs/test.txt
5
  • 4
    Both of your commands are working fine. But a bit slower than Kusalananda's command. I guess, execution time is varying on -exec cat {} \; and -exec -cat {} +. By the way, Thanks a lot Yaron.
    – Rezuan
    Jun 24, 2018 at 13:00
  • xargs is vulnerable to spaces in found pathnames; -exec cat {} is not
    – jez
    Jun 24, 2018 at 21:00
  • 2
    find -print0 | xargs -0 is not vulnerable to spaces/quotes/etc.
    – fluffy
    Jun 24, 2018 at 21:04
  • 1
    @Rezuan: -exec cat {} \; runs cat separately for each file instead of batching them together like xargs. Don't use it unless you explicitly want that (e.g. a command that only works for one file at a time), or if you need portability to a system without -exec ... + and without -print0 / xargs -0. I'm a bit surprised that find|xargs is measurably slower than -exec cat {} +, though. Do you have very few total files, so startup overhead is a lot of the cost? Or did you only time the xargs version while your disk cache was cold? Jun 24, 2018 at 23:06
  • 1
    @PeterCordes thanks for the explanation. It was for the disk cache, I realized later on.
    – Rezuan
    Jun 25, 2018 at 4:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .