5
$\begingroup$

I have twenty data files each contains 1000 lines ("a1.txt, a2.txt....a20.txt"). Now I want to add all these files to a single file and keep the line sequence as followed by the input files (first 1000 from a1.txt, next 1000 from a2.txt and so on). How can I do that?

$\endgroup$
  • $\begingroup$ Hi Xavier and welcome! To make the most of Mma.SE start by taking the tour now. It will help us to help you if you write an excellent question. Edit if improvable, show due diligence, give brief context, include minimal working example of code and data in formatted form. As you receive give back, vote and answer questions, keep the site useful, be kind, correct mistakes and share what you have learned. $\endgroup$ – rhermans Jun 23 '18 at 14:27
  • $\begingroup$ There are things to do after your question is answered. It's a good idea to stay vigilant for some time, better approaches may come later improving over previous replies. Experienced users may point alternatives, caveats or limitations. New users should test answers before voting and wait 24 hours before accepting the best one. Participation is essential for the site, please do your part. $\endgroup$ – rhermans Jun 23 '18 at 14:31
  • $\begingroup$ Oh Yes. I am learning Mathematica for data analysis (in Windows) $\endgroup$ – Xavier Jun 23 '18 at 14:32
  • $\begingroup$ I pointed out an issue to the answer you accepted. Can you comment if that's a problem or not? $\endgroup$ – rhermans Jun 24 '18 at 8:47
4
$\begingroup$

A: Do you need to do this in Mathematica? You can just use the shell command cat in Unix / Mac OS. (This question is the reverse of the question "Splitting a text file into smaller text files by line numbers using Mathematica", which I answered yesterday.)

X: I am learning Mathematica for data analysis (in Windows)

Direct commands

Unix paths are used below -- it is better to construct the file names with FileNameJoin for OS-independent behavior.

fnames = FileNames["~/Downloads/a*.txt"];    
texts = Import /@ fnames;    
Export["~/Downloads/allInOne.txt", StringRiffle[texts, "\n"], "Text"]

Unix / Mac OS

Mentioning this for completeness...

In Unix / Mac OS we can use the command cat. From within Mathematica we can make this call:

Run["cat ~/Downloads/a*.txt > ~/Downloads/allInOne.txt"]
$\endgroup$
  • $\begingroup$ Thanks Anton! Nice solution. $\endgroup$ – Xavier Jun 23 '18 at 14:48
  • $\begingroup$ Ok great, good luck! $\endgroup$ – Anton Antonov Jun 23 '18 at 14:49
  • $\begingroup$ +1 For cat - I did the very same thing just a few days ago. Much simpler than using mathematica $\endgroup$ – Per Alexandersson Jun 23 '18 at 17:54
  • $\begingroup$ @PerAlexandersson Yeah, often enough a Unix commands one-liner is a good alternative to data analysis analysis scripts with other languages/systems. Here is an example, "Command-line Tools can be 235x Faster than your Hadoop Cluster". $\endgroup$ – Anton Antonov Jun 23 '18 at 18:45
  • $\begingroup$ Your solution has the problem that it'a not keeping the order of the files, contrary to the OP's request to " keep the line sequence as followed by the input files". You fnames gives {"a10.txt", "a11.txt", "a12.txt", "a13.txt", "a14.txt", "a15.txt","a16.txt", "a17.txt", "a18.txt", "a19.txt", "a1.txt", "a20.txt", "a2.txt", "a3.txt", "a4.txt", "a5.txt", "a6.txt", "a7.txt", "a8.txt", "a9.txt"}. Presumably the cat` solution suffers from the same? $\endgroup$ – rhermans Jun 24 '18 at 8:43
3
$\begingroup$

OpenRead OpenWrite ReadStringWriteString

Module[
 {
  newfilename = "all.txt",
  wfile, rfile, str
  },
 wfile = OpenWrite[newfilename];
 Table[
  rfile = OpenRead[StringTemplate["File``.txt"][k]];
  str = ReadString[rfile];
  Close[rfile];
  WriteString[wfile, str];
  , {k, 1, 20}
  ];
 Close[newfilename]
 ]

Import and Export

Export[
 "All2.txt",
 StringJoin@Table[
   Import[StringTemplate["File``.txt"][k], "String"]
   , {k, 1, 20}
   ]
 , "String"
 ]

To test my answers I created some files like this

SystemOpen@SetDirectory[$TemporaryDirectory]

Array[
  Export[StringTemplate["File``.txt"][#], (# 1000 + Range[1000]), 
    "CSV"] &
  , 20
  ];

Range[1001, 21000] == Flatten@Import["All.txt", "Table"]
(* True *)

Range[1001, 21000] == Flatten@Import["All2.txt", "Table"]
(* True *)
$\endgroup$
  • $\begingroup$ Thanks rhermans...I am working on it $\endgroup$ – Xavier Jun 23 '18 at 14:47

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.