How to create an empty file from command line
But if newfile already exists and isn’t empty, then touch newfile will leave you with a nonempty file. Maybe not what you wanted.
@CamilleGoudeseune I think If newfile already exists, touch command will just update the timestamp of file (which is what command exactly for) without editing the contents of file.
Will also create an empty file. If the file does already exist, it will be truncated (emptied). To keep the file contents, use >> for appending as in:
Even if the file exists, the contents will be untouched.
Edit: If you don’t have any content to type, this one is faster:
user@host$ :> newfile user@host$ :>> new_or_existing_file
Note. : is the command here. It is not part of the prompt.
If you want to create as root
To not truncate existing file:
I don’t think so. Any shell which allows redirection of output stream to a file should support this. This will truncate the file if it already exists. touch is safe to use if you don’t want to empty it.
the exact way there is also another way
The difference is file1.ext will be zero bytes and file2.ext would be one byte. You can check this by
No, ‘echo «» >’ does not create an empty file, it creates a file containing a newline. If you for some reason want to use echo to create an empty file you will have to use ‘echo -n «» >’, or simply ‘echo -n >’
Using vim editor you can also create an empty file.
creates an empty file, if your version of echo supports the -n switch.
In general, creating any regular 1 file on Linux involves open(2) , openat(2) , and creat(2) system calls (and specifically with O_CREAT flags). That means if you call any command-line utility that does these system calls, you can create a new empty file.
Most commonly new filename is created with something like this:
- touch /tmp/new_file
- : > /tmp/new_file
- true > /tmp/new_file
- > /tmp/new_file ( bash shell only )
touch is a standalone utility. Its original purpose is to update the access and modification time of a file, however if the file does not exist — it will be created. Note also that a filename — is treated specially, so if you do want to create a file that is named literally — , you’ll have to enclose that into single or double quotes.
By contrast, > is a shell redirection operator for stdout stream. The > operator specifically calls the openat() system call with O_WRONLY|O_CREAT|O_TRUNC flags. That means, if the filename does not exist — it will be created, and if it does — the data will be truncated (and therefore gone, so > should be used with care). In most shells nowadays true or : is a built-in , so doing : > /tmp/new_file is going to be more efficient, although marginally compared to touch /tmp/new_file .
But of course it does not stop there. As mentioned, anything that can perform open() , openat() and, create() syscalls will create a file. Hence, we can do:
- true|dd of=/tmp/newfile
- truncate —size 0 /tmp/new_filename.txt
- cp /dev/null /tmp/null_file
- true|tee /tmp/some_other_file
- mktemp or tempfile ( for creating temporary files that do not need to exist between reboots !)
Of course, all the above mentioned utilities do not exclusively create files. But they perform the necessary syscall and that allows us to adapt the commands.
Of course, at the level of programming or scripting we may want to create a file as well, especially for efficiency purposes (because calling external commands such as touch from a Perl script or Python will require additional resources).
$ python -c 'import sys,os;f=sys.argv[1];os.utime(f,None) if os.path.exists(f) else open(f,"a").close' myfile.txt
We can make it shorter with this:
$ python -c 'import sys,os;f=sys.argv[1];'$'\n''with open(f,"a"): os.utime(f,None)' mysecondfile.txt
$ perl -e 'open(my $fh,">","/tmp/perlfile")'
1 Other types of files such as hard/soft links,character or block special devices, directory,named pipes, or sockets require entirely different syscalls.
Fastest way to create a new file with a specific number of zero’s
I have a directory tree that in each directory there is a file called zero-file
I want this file to be initialized with specific number of zero’s for example 10000000000.
I want to write ASCII character ‘0’
I found 2 solutions for this
for i in `seq 1 10000000000` do echo -n 0 >> zero-file done
3 Answers 3
Try using /dev/zero as a virtual input file that contains only zeros. You can copy a fixed number of bytes with dd :
dd if=/dev/zero of=zero-file bs=1 count=10000000000
This copies one byte 10000000000 times from /dev/zero to zero-file . You can adjust the blocksize and count as needed.
To write zeros to zero-file:
dd if=/dev/zero bs=1 count=10000000000 | tr '\0' '0' > zero-file
This version creates binary zeros, then translates them to the ASCII character ‘0’ . I thought you wanted real binary zeros, not the character (which is really 48). After the clarification that you want ‘0’ (ASCII character) instead of ‘\0’ (binary value zero), I think this is the version you’d want.
If the file length is a large multiple of e.g. 1000 or 1024, I would instead set bs=1000 or bs=1024 and divide count by the same number; that should be faster (because dd would use a buffer)
As noted by @BasileStarynkevitch it is often possible to increase the performance with a larger blocksize (bs). Example: dd if=/dev/zero bs=1000000 count=10000 | tr ‘\0’ ‘0’ > zero-file . Important: You need blocksize in bytes as available RAM.
according to @Cyrus answer:
dd if=/dev/zero bs=1 count=10000000000 | tr '\0' '0' > zero-file
I have a directory tree that in each directory there is a file called zero-file
so you have to do this command several time
My idea is to save it in a file once and for the other directories use that file that contains those 0’s.
#for the first time $ dd if=/dev/zero bs=1 count=10000000000 | tr '\0' '0' > zero-file #for other directories $ dd if=../zero-file of=zero-file bs=1 count=10000000000
How do I create an empty file (0 byte size) in all the directories?
Recently I was asked, in a job interview, «how to create a zero size file [I think that means an empty file] in all the folders of the file system?» I found the question a bit strange, I thought of a loop to list all the directory and use touch or maybe go to the root directory and use touch with a recursive option. Do you have any ideas?
That question is strange in that it’s asking for something completely useless. That said, it’s not at all strange for an interview question in that it’s asking for something completely useless.
There are certainly more useful cases for this than @ikkachu thinks. For instance, a git template directory structure. Git just handles files, not directories, which just come as kind of a «side-effect» of file paths. Therefore, having at least one file in each directory is a must to have otherwise empty directories make it into a git repo. There are certainly more real-life use cases for such a requirement.
4 Answers 4
find . -type d -exec touch <>/emptyfile \;
- -type d means «directories»
- exec ute the command touch and create a file named «emptyfile»
- the <> substitutes what is found as a result from find . The / is to make it a valid path+filenane and the escaped ; is to close the command (otherwise it becomes «emptyfile;»)
rinzwind@schijfwereld:~/t$ mkdir 1 2 3 4 5 6 7 8 9 10 rinzwind@schijfwereld:~/t$ ls -ltr */* ls: cannot access '*/*': No such file or directory rinzwind@schijfwereld:~/t$ find . -type d -exec touch <>/emptyfile \; rinzwind@schijfwereld:~/t$ ls -ltr */* -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 5/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 9/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 1/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 8/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 3/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 2/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 10/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 7/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 6/emptyfile -rw-rw-r-- 1 rinzwind rinzwind 0 apr 16 19:57 4/emptyfile
Mine works but the answer from Peter Cordes is better 🙂
I was curious if we can speed this up with -exec . + in GNU find. No, <>/emptyfile isn’t supported with + , only ; . So you’d want find -print0 | xargs -0 to avoid starting a touch process for every directory in the FS (which is presumably a lot, and if you’re lucky some of the IO will be contiguous and might not be a bottleneck.)
(I posted an answer with find -printf | xargs -0 that only has to run touch once per ARG_MAX files created.)
Awesome answer! Would you mind explaining what you mean by «the escaped ; is to close the command»? What if you leave the semicolon out?
@TheUnknownDev: Then find would complain that there was no end to the ; -terminated or + -terminated series of args that follow the -exec . Try find -exec echo ‘<>‘ in a test directory. You need to tell it whether to batch args onto one command, or run the command separately for each file, by using + or \; .
@PeterCordes thanks 😀 Oh and good one on your answer. I will -not- alter mine as that would be me changing my answer to yours 😉 I assume TS will remove the accepted answer and accpets yours,
To do this efficiently, you want to avoid spawning a new touch process for every file you want to create.
This is part of what xargs is good for, batching args into chunks as large as possible, while small enough to fit on the command line of a single process. (Modern Linux has pretty huge limits so it’s rarely a problem anymore, xargs rarely has to actually run your command multiple times to handle all the args, but it also lets you avoid having filename subjected to shell word-splitting like in foo $(bar) .)
We can use find’s own -printf to format additional stuff onto each directory path, specifically the filename we want. The xargs -0 uses a ‘\0’ byte as a separator so this is safe with arbitrary filenames, even including newline. If you weren’t using a custom printf format, you could just use -print0 to print 0-separated paths.
find . -xdev -type d -printf '%p/empty\0' | xargs -0 echo touch
(in a test directory, that prints touch ./empty ./2/empty ./1/empty , not touch ./empty , touch ./1/empty , etc. so it’s running one touch for multiple files.)
mktemp only accepts a single template, but if we want some randomness in the naming to reduce the chance of just touching an existing file by accident, you could do this.
find . -xdev -type d -printf "%p/empty.$RANDOM\0" | xargs -0 echo touch
Note that it’s the same 15-bit random number in every directory, because «$RANDOM» is expanded once by bash before find starts. You could use $(date +%s).$RANDOM or whatever you want as part of the filename.
With an SSD or tmpfs, CPU might be the bottleneck here. Or if you’re lucky and metadata I/O on a magnetic disk happens to be mostly contiguous because you’re touching every directory (and allocating a bunch of new inodes), even a rotational disk could maybe keep up somewhat decently. Although you’re probably not touching directories in the order they’re laid out on disk.
And regardless, there’s no need to waste lots of CPU time starting processes for something that should be I/O limited.
Ways that don’t work:
- find -exec touch <> + batches args, but -exec touch <>/empty + refuses to work when <> isn’t by itself.
- xargs -I <> echo touch <>/emptyfile implies -L 1 (only process one «line» of input for each invocation of the command, whether that’s an actual line or a 0-separated string with xargs -0 ). So we can’t use xargs to modify each arg if we want to take advantage of it for batching args.