Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-23T15:45:49.370Z
Answers.Text: 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.
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-23T15:51:01.467Z
Answers.Text: @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...`.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-24T15:55:09.023Z
Answers.Text: 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!
Answers.UserDisplayName: rimo
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-24T16:08:49.843Z
Answers.Text: @rimo yes, exactly, macOS ships with a different `find` implementation that might not support all of the flags used like `-maxdepth`. `-empty` and `-delete`.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-23T15:00:59.940Z
Answers.LastActivityDate: 2023-01-24T16:09:48.353Z
Answers.LastEditDate: 2023-01-24T16:09:48.353Z
Answers.UserDisplayName: terdon
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-20T20:48:00.510Z
Answers.Text: I saw that link too and tried it but it didn't work for some reason
Answers.UserDisplayName: rimo
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-20T21:58:14.937Z
Answers.Text: What happened when you tried it?
Answers.UserDisplayName: Scot
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-20T22:33:52.723Z
Answers.Text: it doesn't do anything...nothing output in the STDOUT and nothing changed in the directory
Answers.UserDisplayName: rimo
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-20T23:24:18.860Z
Answers.Text: 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.
Answers.UserDisplayName: Ram RS
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-23T14:49:53.777Z
Answers.Text: @rimo Ram's solution only works on Linux systems, what are you using?
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-24T15:49:17.597Z
Answers.Text: I'm using a mac OS which is probably why that doesn't work for me
Answers.UserDisplayName: rimo
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-24T15:54:41.537Z
Answers.Text: 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.
Answers.UserDisplayName: Ram RS
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-20T20:44:31.390Z
Answers.LastActivityDate: 2023-01-20T20:44:31.390Z
Answers.UserDisplayName: Ram RS
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-21T11:24:35.630Z
Answers.LastActivityDate: 2023-01-23T14:57:27.600Z
Answers.LastEditDate: 2023-01-23T14:57:27.600Z
Answers.UserDisplayName: Steve
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-20T22:33:09.050Z
Answers.Text: 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.
Answers.UserDisplayName: rimo
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-21T03:44:10.217Z
Answers.Text: 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.
Answers.UserDisplayName: Scot
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-21T11:36:32.070Z
Answers.Text: If `find` doesn't return any results, a pipe to `xargs rm -rf` could remove everything in your current directory.
Answers.UserDisplayName: Steve
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-21T12:40:49.017Z
Answers.Text: @Steve the point was addressed above
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-23T14:53:09.567Z
Answers.Text: 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.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-23T15:11:17.023Z
Answers.Text: @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.
Answers.UserDisplayName: terdon
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-23T15:17:35.400Z
Answers.Text: Okay I err ....
Answers.UserDisplayName: M__
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-24T15:59:43.747Z
Answers.Text: 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.
Answers.UserDisplayName: Ram RS
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-20T22:28:03.020Z
Answers.LastActivityDate: 2023-01-23T14:53:57.047Z
Answers.LastEditDate: 2023-01-23T14:53:57.047Z
Answers.UserDisplayName: M__
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-01-20T21:24:13.497Z
Comments.Text: 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.
Comments.UserDisplayName: Scot
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-01-21T13:16:34.790Z
Comments.Text: If you try `find` with `-links` and let me know
Comments.UserDisplayName: M__
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-01-23T14:49:16.687Z
Comments.Text: What operating system are you using? Not all `find` implementations have the `-empty` or `-delete` flags.
Comments.UserDisplayName: terdon
Tags: <fasta><bash><grep><command-line>
Title: How to remove empty files from a directory?
ThreadText: # 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 @username_4 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:
  
  ```sh
  for file in *.fasta; do 
   [[ $(wc -l < "$file") -eq 0 ]] && echo rm -- "$file"
  done
  
  ```
  
  If you want to recursively descend into subdirectories, use:
  
  ```sh
  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**: @username_2 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**: @username_0 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**: @username_0 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](https://www.nextflow.io/) pipeline. Unless the default [publishDir](https://www.nextflow.io/docs/latest/process.html#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
  
  @username_4 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 @username_5'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**: @username_5 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**: @username_2 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.  
  
  ---
  
  