11

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.

Rezuan
  • 243

2 Answers2

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:

Kusalananda
  • 333,661
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
Yaron
  • 4,289
  • 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 '18 at 13:00
  • xargs is vulnerable to spaces in found pathnames; -exec cat {} is not – jez Jun 24 '18 at 21:00
  • 2
    find -print0 | xargs -0 is not vulnerable to spaces/quotes/etc. – fluffy Jun 24 '18 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? – Peter Cordes Jun 24 '18 at 23:06
  • 1
    @PeterCordes thanks for the explanation. It was for the disk cache, I realized later on. – Rezuan Jun 25 '18 at 04:14