9

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.

  • You still need to use cat. – Ignacio Vazquez-Abrams Jun 24 '18 at 12:40
  • Yes! Can you please tell me how can I do that? @IgnacioVazquez-Abrams – Rezuan Jun 24 '18 at 12:41
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
    Working as expected and execution time is very fast which is really great. Many thanks. – Rezuan Jun 24 '18 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
  • 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 4:14

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.