<p>This isn't the most efficient approach, using <code>find</code> will be easier and faster as long as your <code>find</code> supports the <code>-empty</code> option, but since this is what you asked for, here is how to do it based on the number of lines:</p>
<pre class="lang-sh prettyprint-override"><code>for file in *.fasta; do 
 [[ $(wc -l &lt; &quot;$file&quot;) -eq 0 ]] &amp;&amp; echo rm -- &quot;$file&quot;
done
</code></pre>
<p>If you want to recursively descend into subdirectories, use:</p>
<pre class="lang-sh prettyprint-override"><code>shopt -s globstar
for file in  *.fasta */**.fasta; do.
  [[ $(wc -l &lt; &quot;$file&quot;) -eq 0 ]] &amp;&amp; echo rm -- &quot;$file&quot;
done
</code></pre>
<p>If that prints the right files, remove the <code>echo</code> to actually delete them.</p>
<p>Note that this will also delete files that are not empty but don't have a newline character. These are not valid &quot;text files&quot;, but strictly speaking they aren't empty, they just have no <em>lines</em> as lines are defined by the <code>\n</code> character. For example, this file would be deleted:</p>
<pre><code>printf 'aaa' &gt; file
</code></pre>

CC BY-SA 4.0
2023-01-23T15:45:49.370Z
The potential problem with this approach in Nextflow is there are "extensive" (or more than I think reasonable) numbers of subdirectories in the output and the names get complicated, which precisely is why I avoid it  (I'd rather construct my own Dockerfiles). `find` will run straight through the directory structure and the depth can be set. Thats why in my opinion it's the favoured solution here.
M__
CC BY-SA 4.0
2023-01-23T15:51:01.467Z
@M__ yes, absolutely. If the OP's `find` supports the `-empty` and `-delete`, it is the best tool for the job. You could easily make this recursive with `shopt -s globstar; for file in 
*.fasta */**.fasta; do...`.
terdon
CC BY-SA 4.0
2023-01-24T15:55:09.023Z
thank you so much for this line of code!! and the comments really help too. I am running this with a mac OS which is why I think the find function doesn't work for me. It definitely seems like the easier option so I might try and find a workaround with an aws instance in the future but for now this works like a charm. Thank you!
rimo
CC BY-SA 4.0
2023-01-24T16:08:49.843Z
@rimo yes, exactly, macOS ships with a different `find` implementation that might not support all of the flags used like `-maxdepth`. `-empty` and `-delete`.
terdon
CC BY-SA 4.0
2023-01-23T15:00:59.940Z
2023-01-24T16:09:48.353Z
2023-01-24T16:09:48.353Z
terdon
<p>Always Google before asking on forums. I googled &quot;delete empty files linux&quot; and this was the second result: <a href="https://www.baeldung.com/linux/delete-empty-files-dirs" rel="nofollow noreferrer">https://www.baeldung.com/linux/delete-empty-files-dirs</a></p>
<pre><code># Print and delete empty files just in the current directory
$ find . -maxdepth 1 -type f -empty -print -delete
# Print and delete empty files in the current directory and all sub-directories
$ find . -type f -empty -print -delete
</code></pre>

CC BY-SA 4.0
2023-01-20T20:48:00.510Z
I saw that link too and tried it but it didn't work for some reason
rimo
CC BY-SA 4.0
2023-01-20T21:58:14.937Z
What happened when you tried it?
Scot
CC BY-SA 4.0
2023-01-20T22:33:52.723Z
it doesn't do anything...nothing output in the STDOUT and nothing changed in the directory
rimo
CC BY-SA 4.0
2023-01-20T23:24:18.860Z
Are you running the command from the right directory? If it does not delete anything, but you're sure you have "empty" files, check if the files have blank spaces or some such invisible characters. `cat -A` them.
Ram RS
CC BY-SA 4.0
2023-01-23T14:49:53.777Z
@rimo Ram's solution only works on Linux systems, what are you using?
terdon
CC BY-SA 4.0
2023-01-24T15:49:17.597Z
I'm using a mac OS which is probably why that doesn't work for me
rimo
CC BY-SA 4.0
2023-01-24T15:54:41.537Z
It should work on macOS too - it's not because of the OS, it's because of the file type. Empty aliases are not empty files, much like how empty directories are not empty files. Define your tasks more specifically and you'll be able to get to an accurate answer quicker.
Ram RS
CC BY-SA 4.0
2023-01-20T20:44:31.390Z
2023-01-20T20:44:31.390Z
Ram RS
<p>As already stated, one way is to use the GNU <code>find</code> (the default on Linux) command. This will find and print all empty files in the current directory:</p>
<pre><code>find . -maxdepth 1 -type f -empty -print
</code></pre>
<p>Append the <code>-delete</code> action to the command above when you're ready to remove them. If you need to find (and then delete) empty files recursively, simply remove the <code>-maxdepth 1</code> option.</p>
<hr />
<hr />
<p>In a comment, you mention that these are actually &quot;alias&quot; files which are the results of a <a href="https://www.nextflow.io/" rel="nofollow noreferrer">Nextflow</a> pipeline. Unless the default <a href="https://www.nextflow.io/docs/latest/process.html#publishdir" rel="nofollow noreferrer">publishDir</a> mode has been changed, Nextflow will publish output files to the publishDir using symbolic links to the files in the working directory (i.e. <code>./work</code>). I suspect what you are trying to do is to find and remove the links to these empty files, but not the files themselves. In this case, I think what you want is:</p>
<pre><code>find . -type l -exec test ! -s '{}' \; -print
</code></pre>
<p>Again, append the <code>-delete</code> action to the command above to actually remove the symlinks. If you instead need to delete files from Nextflow's working directory, use <code>nextflow clean</code> in conjunction with <code>nextflow log</code> to safely clean up the failed runs.</p>

CC BY-SA 4.0
2023-01-21T11:24:35.630Z
2023-01-23T14:57:27.600Z
2023-01-23T14:57:27.600Z
Steve
<p>@Ram RS has identified the solution here via <code>find</code>, if that does not work then the following will work,</p>
<pre><code>find . -maxdepth 1 -type f -empty | xargs rm 
</code></pre>
<hr />
<p><strong>Edit 2</strong></p>
<p>The solution is obvious ...</p>
<pre><code>find . -type l -delete
</code></pre>
<p>The code under <strong>Edit</strong> is is better if the OP knows in advance <em>precisely</em> how many links the symbolic link file has, basically its always one. However, we don't know, thus <code>-type l</code> will delete every symbolic link.</p>
<hr />
<p>To address @Steve's point of inadvertent deletion in case of a null return ... The code was checked prior release and this didn't occur (and also now rechecked).</p>

CC BY-SA 4.0
2023-01-20T22:33:09.050Z
I think the issue I'm facing is that these files are "Alias" files which are the results from a Nextflow script I wrote. Therefore, the file has size (~180 bytes) but is ultimately empty inside. I think the solution I am looking for is more specific than using the "find" command because it's not working for me. I would like to try and use a solution that actively looks in the files and sees whether there is text there (i.e. wc -l < 1) and if not, delete the file.
rimo
CC BY-SA 4.0
2023-01-21T03:44:10.217Z
Or change the scope of what you are doing to only make softlinks to files that are greater than 0 bytes in size, rather than deleting the ones you already have made.
Scot
CC BY-SA 4.0
2023-01-21T11:36:32.070Z
If `find` doesn't return any results, a pipe to `xargs rm -rf` could remove everything in your current directory.
Steve
CC BY-SA 4.0
2023-01-21T12:40:49.017Z
@Steve the point was addressed above
M__
CC BY-SA 4.0
2023-01-23T14:53:09.567Z
if the `-delete` fails, that is most likely because the OP is using a `find` version that doesn't have it, so will very likely also not support the `-empty`. Also, note that this will fail on weird file names (which shouldn't be an issue with fasta files, but you never know). More importantly, your "edit" section does not remove symbolic links, the `-links` predicate is about the number of _hard_ links. Since most inodes only have a single hard link (the file), your command will simply delete all files in the directory.
terdon
CC BY-SA 4.0
2023-01-23T15:11:17.023Z
@M__ no, it will not remove symbolic links. Or, more accurately, it will remove all files, which includes symbolic links so in that sense it will remove symbolic links. See `man find` where the `-links` option is documented and where it explains that it refers to hard links and also just try `touch file{1..10}` and then run `find . -type f -links 1 -print -delete` and you will see that all 10 of the files you created will be removed. And yes, the first point applies to all, but the OP commented here hence I left the comment here to explain why it failed for them.
terdon
CC BY-SA 4.0
2023-01-23T15:17:35.400Z
Okay I err ....
M__
CC BY-SA 4.0
2023-01-24T15:59:43.747Z
I don't understand how an Alias file (or even a symlink for that matter) can be considered empty. Is the alias/link empty when the file pointed to is empty? Or is it empty when the file pointed to does not exist? I'm unable to understand OP's situation.
Ram RS
CC BY-SA 4.0
2023-01-20T22:28:03.020Z
2023-01-23T14:53:57.047Z
2023-01-23T14:53:57.047Z
M__
<p>I have a directory of FASTA files, some of which are empty (placeholders that were output from a pipeline) and I would like to delete the empty files using a for loop on the command line.</p>
<p>From what I have seen so far I can use the <code>wc -l [file]</code> approach to see &quot;if there are lines present, delete the file&quot; but I want to make sure the syntax is right before deleting important files. I was thinking it might be easier for the command to look for the &quot; &gt; &quot; symbol found at the header in FASTA files and if it's not present delete the file.</p>
<p>Here is what I have so far:</p>
<pre><code>for file in *.fasta; do &quot;if wc -l &lt; 1 rm file&quot;; done
</code></pre>
<p>Or</p>
<pre><code>for file in *.fasta; do &quot;grep &gt; | rm file&quot;; done
</code></pre>

CC BY-SA 4.0
2023-01-20T21:24:13.497Z
You'll want to use the `find` command, as the answer from @Ram RS shows. But on a separate note, neither of the above commands are syntactically correct. For a safe way to use these commands & test them, substitute `ls` for `rm`, to simply list files rather than delete them.
Scot
CC BY-SA 4.0
2023-01-21T13:16:34.790Z
If you try `find` with `-links` and let me know
M__
CC BY-SA 4.0
2023-01-23T14:49:16.687Z
What operating system are you using? Not all `find` implementations have the `-empty` or `-delete` flags.
terdon
<fasta><bash><grep><command-line>
How to remove empty files from a directory?
# How to remove empty files from a directory?

(Asked by: username_0 on 2023-01-20)

I have a directory of FASTA files, some of which are empty (placeholders that were output from a pipeline) and I would like to delete the empty files using a for loop on the command line.
From what I have seen so far I can use the wc -l [file] approach to see "if there are lines present, delete the file" but I want to make sure the syntax is right before deleting important files. I was thinking it might be easier for the command to look for the " > " symbol found at the header in FASTA files and if it's not present delete the file.
Here is what I have so far:
for file in *.fasta; do "if wc -l < 1 rm file"; done

Or
for file in *.fasta; do "grep > | rm file"; done

**Tags:** fasta, bash, grep, command-line
> **Comments:**
> **username_1**: You'll want to use the `find` command, as the answer from @Ram RS shows. But on a separate note, neither of the above commands are syntactically correct. For a safe way to use these commands & test them, substitute `ls` for `rm`, to simply list files rather than delete them.  
> **username_2**: If you try `find` with `-links` and let me know  
> **username_3**: What operating system are you using? Not all `find` implementations have the `-empty` or `-delete` flags.  

---

## 4 answers

### Answer by username_3 on 2023-01-23. Score: 2 | Accepted answer

This isn't the most efficient approach, using find will be easier and faster as long as your find supports the -empty option, but since this is what you asked for, here is how to do it based on the number of lines:
for file in *.fasta; do 
 [[ $(wc -l < "$file") -eq 0 ]] && echo rm -- "$file"
done

If you want to recursively descend into subdirectories, use:
shopt -s globstar
for file in  *.fasta */**.fasta; do.
  [[ $(wc -l < "$file") -eq 0 ]] && echo rm -- "$file"
done

If that prints the right files, remove the echo to actually delete them.
Note that this will also delete files that are not empty but don't have a newline character. These are not valid "text files", but strictly speaking they aren't empty, they just have no lines as lines are defined by the \n character. For example, this file would be deleted:
printf 'aaa' > file

> **Comments:**
> **username_2**: The potential problem with this approach in Nextflow is there are "extensive" (or more than I think reasonable) numbers of subdirectories in the output and the names get complicated, which precisely is why I avoid it  (I'd rather construct my own Dockerfiles). `find` will run straight through the directory structure and the depth can be set. Thats why in my opinion it's the favoured solution here.  
> **username_3**: @M__ yes, absolutely. If the OP's `find` supports the `-empty` and `-delete`, it is the best tool for the job. You could easily make this recursive with `shopt -s globstar; for file in  *.fasta */**.fasta; do...`.  
> **username_0**: thank you so much for this line of code!! and the comments really help too. I am running this with a mac OS which is why I think the find function doesn't work for me. It definitely seems like the easier option so I might try and find a workaround with an aws instance in the future but for now this works like a charm. Thank you!  
> **username_3**: @rimo yes, exactly, macOS ships with a different `find` implementation that might not support all of the flags used like `-maxdepth`. `-empty` and `-delete`.  

---

### Answer by username_4 on 2023-01-20. Score: 3

Always Google before asking on forums. I googled "delete empty files linux" and this was the second result: https://www.baeldung.com/linux/delete-empty-files-dirs
# Print and delete empty files just in the current directory
$ find . -maxdepth 1 -type f -empty -print -delete
# Print and delete empty files in the current directory and all sub-directories
$ find . -type f -empty -print -delete

> **Comments:**
> **username_0**: I saw that link too and tried it but it didn't work for some reason  
> **username_1**: What happened when you tried it?  
> **username_0**: it doesn't do anything...nothing output in the STDOUT and nothing changed in the directory  
> **username_4**: Are you running the command from the right directory? If it does not delete anything, but you're sure you have "empty" files, check if the files have blank spaces or some such invisible characters. `cat -A` them.  
> **username_3**: @rimo Ram's solution only works on Linux systems, what are you using?  
> **username_0**: I'm using a mac OS which is probably why that doesn't work for me  
> **username_4**: It should work on macOS too - it's not because of the OS, it's because of the file type. Empty aliases are not empty files, much like how empty directories are not empty files. Define your tasks more specifically and you'll be able to get to an accurate answer quicker.  

---

### Answer by username_5 on 2023-01-21. Score: 2

As already stated, one way is to use the GNU find (the default on Linux) command. This will find and print all empty files in the current directory:
find . -maxdepth 1 -type f -empty -print

Append the -delete action to the command above when you're ready to remove them. If you need to find (and then delete) empty files recursively, simply remove the -maxdepth 1 option.


In a comment, you mention that these are actually "alias" files which are the results of a Nextflow pipeline. Unless the default publishDir mode has been changed, Nextflow will publish output files to the publishDir using symbolic links to the files in the working directory (i.e. ./work). I suspect what you are trying to do is to find and remove the links to these empty files, but not the files themselves. In this case, I think what you want is:
find . -type l -exec test ! -s '{}' \; -print

Again, append the -delete action to the command above to actually remove the symlinks. If you instead need to delete files from Nextflow's working directory, use nextflow clean in conjunction with nextflow log to safely clean up the failed runs.


---

### Answer by username_2 on 2023-01-20. Score: 1

@Ram RS has identified the solution here via find, if that does not work then the following will work,
find . -maxdepth 1 -type f -empty | xargs rm 


Edit 2
The solution is obvious ...
find . -type l -delete

The code under Edit is is better if the OP knows in advance precisely how many links the symbolic link file has, basically its always one. However, we don't know, thus -type l will delete every symbolic link.

To address @Steve's point of inadvertent deletion in case of a null return ... The code was checked prior release and this didn't occur (and also now rechecked).

> **Comments:**
> **username_0**: I think the issue I'm facing is that these files are "Alias" files which are the results from a Nextflow script I wrote. Therefore, the file has size (~180 bytes) but is ultimately empty inside. I think the solution I am looking for is more specific than using the "find" command because it's not working for me. I would like to try and use a solution that actively looks in the files and sees whether there is text there (i.e. wc -l < 1) and if not, delete the file.  
> **username_1**: Or change the scope of what you are doing to only make softlinks to files that are greater than 0 bytes in size, rather than deleting the ones you already have made.  
> **username_5**: If `find` doesn't return any results, a pipe to `xargs rm -rf` could remove everything in your current directory.  
> **username_2**: @Steve the point was addressed above  
> **username_3**: if the `-delete` fails, that is most likely because the OP is using a `find` version that doesn't have it, so will very likely also not support the `-empty`. Also, note that this will fail on weird file names (which shouldn't be an issue with fasta files, but you never know). More importantly, your "edit" section does not remove symbolic links, the `-links` predicate is about the number of _hard_ links. Since most inodes only have a single hard link (the file), your command will simply delete all files in the directory.  
> **username_3**: @M__ no, it will not remove symbolic links. Or, more accurately, it will remove all files, which includes symbolic links so in that sense it will remove symbolic links. See `man find` where the `-links` option is documented and where it explains that it refers to hard links and also just try `touch file{1..10}` and then run `find . -type f -links 1 -print -delete` and you will see that all 10 of the files you created will be removed. And yes, the first point applies to all, but the OP commented here hence I left the comment here to explain why it failed for them.  
> **username_2**: Okay I err ....  
> **username_4**: I don't understand how an Alias file (or even a symlink for that matter) can be considered empty. Is the alias/link empty when the file pointed to is empty? Or is it empty when the file pointed to does not exist? I'm unable to understand OP's situation.  

---

