I have saved many documents as txt. I want to print them together so first I want them together in a single file. The order doesn't matter in this case.
I want a solution that does not involve typing the names of the files to be merged, but one that would just merge all txt files within the folder.
Can I do it with a command or some GUI?
I looked here. Don't know how to use join.
8 Answers
Use cat with output redirection. Syntax: cat file [file] [[file] ...] > joined-file.
Example with just two files (you can have many more):
$ echo "some text in a file" > file1
$ echo "another file with some text" > file2
$ cat file1 file2 > mergedfiles
$ cat mergedfiles
some text in a file
another file with some textIn case you have "many documents", make use of shell globbing (patterns):
cat input-files-dir/* > joined-fileThis will join all files in that directory to the current directory (preventing it to match the output file itself). It is totally independent to the use of cat and output redirection - it's just Bash providing all the files as arguments to cat.
File types
It will just glue (join) files together as you would do with paper and tape. It does not care about the actual file format being capable of handling this. It will work for text files, but not for PDFs, ODTs, etc. Well, it will glue them together, but it's not a valid PDF/ODT anymore.
Order of joining
As phoibos pointed out the shell globbing will result in alphabetical order of file names. This is how Bash and shell globbing works.
Addendum about input file is output file error
When the pattern of the input files matches the very same file as being output, this will cause an error. It's a safety feature. Example: cat *.txt > out.txt run the second time will cause this.
What you can do about it:
- Choose a more specific pattern to match the actual input files, not matching the output name. Example: input files pattern
*.txtwith output fileoutput.outwill not collide. - Work in different directories. In the example above I've used a separate
input-files-dirdirectory to place all files in, and output to the current working directory. This makes it impossible to get this error.
A simple way to do that is by using cat:
cat file1 file2 > joined_fileIf you just issue cat file1 file2 you'll see both files on the standard output. By using >, you're just redirecting the standard output to a file. That will work also with another commands.
Do it with a simple loop:
for i in *.txt; do cat "$i" >> complete.txt; done>> appends to the file.
Note: If for some reason you have to run the command again, you have to remove complete.txt, otherwise you'd write the file to itself, which doesn't work.
If the files you want to combine all end in .txt, keep it simple:
cat *.txt > combined.txtIf the directory only contains text files, it's also simple:
cat * > combined.txt(Note that once you create combined.txt, doing it again would include it in the expansion of *, leading to odd behavior).
If you want to select some files in the directory and not others, it's best if the filenames allow you to distinguish which ones you want. If not, you can get fancy with find. But I doubt you need to go that far.
Thunar custom action script written by cipricus also inspired me to write a similar Nautilus script and I thought it might be useful for others who look at this Q&A for reference on this subject. So here it is:
#!/bin/sh
#Nautilus Script to join selected text files in a single file and open the joined file with default text editor
#
IFS=$'\n'
FILENAME="JoinedFile_$(date +%Y-%m-%d-%H-%M-%S).txt"
cat "$@" > "$FILENAME"
xdg-open "$FILENAME" 2 This is a complement and a variation to the other answers, related to putting these solutions to work in Thunar's custom's actions.
Not all of them are usable in this way, but some are.
I thought that most interesting would be to be able to merge selected files from Thunar's context menu.
This is a variation from what was suggested by Sadi in a comment to gertvdijk's answer :
cat %N > JoinedFileOnly selected files will be joined. Restrict appearance conditions to text files.
Special thanks to Sadi whose comment provided me with the most clear and up-to-point solution to my problem.
I accepted gertvdijk's answer as definitive. Not only it was the occasion to Sadi's comment, but is seems to be of further value to others, providing a well argued and complete solution (albeit somewhat above my CLI reading skills).
You could try find command also,
find . -name "*.txt" -type f -exec cat {} + > fileIt finds .txt files inside the current directory and execute cat command on each founded file. Finally the whole output was redirected to the filename file(created within the current directly itself).
Explanation:
. # current directory
-name # helps to find only .txt files.
-type f # Only files
-exec cat {} + # helps to run cat command on the founded .txt files.
> # Output redirection operator
file # to store final output. You could also just use an online utility such as merge-files-online.com