Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is there a command that allows finding out whether or not a file contains something?

I tried with ls' size option (ls -lsh) but it does not show me the empty files because the files/folders have no size.

share|improve this question
    
Well, if the file size is zero, there's nothing inside the file. Isn't that right ? – Serg Mar 14 at 23:15
    
@Serg yeah man thats what i mean , can u help me with this? – Ziadd Hosary Mar 14 at 23:21
1  
can you please accept kos's answer as the correct one ? I need to remove mine – Serg Mar 15 at 3:59
up vote 4 down vote accepted

We could analyse a file by the size using du command.

$> du Desktop/datasheet-3347.pdf                                
3564    Desktop/datasheet-3347.pdf

However, there's a small catch. What do we mean by the empty file ? Be aware that there are files with non-printable characters. Here's an example:

$> touch myFile.txt                                                            
$> echo '' > myFile.txt
$> du myFile.txt
4   myFile.txt

Look ! I've echoed empty space into the file, and yet it reports some size in bytes ? how can that be ?! Well, we've still written a single newline to the file.

As shown in this brilliant answer, files on disks are in chunks of 4096 bytes. When we write just a few bytes to the disk, the operating system still allocates a chunk of 4096 bytes. So technically file here is empty from human-readable point of view, and yet - it contains bytes.

We can create reference to a file , which will be 0 bytes, but once we try to fill it with any data, we'll give it 4096 bytes

$> touch myFile2.txt                                                           
$> du myFile2.txt
0   myFile2.txt

But why directory is 4096 bytes ? directories are sort of lists. Once you create a directory, even empty one, it holds information (for those interested in C programming language, that's dirent structure , which contains inode number, record length, type, and name; lookup dirent.h). So even though directory may not have files, it will contain information about itself.

share|improve this answer
    
Thanks for the explanation ,your awesome – Ziadd Hosary Mar 15 at 0:12
1  
Serg, thats not right..FS stores data as blocks on disk and minimum block size for ext is 4K, not 512B..512B could be the physical sector size IIRC.. – heemayl Mar 15 at 1:26
    
du always reporting in 4K chunks on my system..du -b shows the actual file size in bytes, not how much space it has taken on disk..try plain du.. – heemayl Mar 15 at 1:41
    
I have no complaint over your selection of du -b..i am saying the part you have written about block size on disk is wrong..../sys is provided by kernel and is a tmpfs (resides on memory), you should see the files as zero sized as sysfs should not show the size of any file on /sys as it depends on the time of read.. – heemayl Mar 15 at 2:02
    
I think that your example is confusing, especially the part I've echoed empty space into the file which is wrong: echo '' has written a new line because the -n option has not been used. It can be confusing for people who don't know how echo works. Can you please find an explicit example? – A.L Mar 15 at 12:41

You can use test with -f and ! -s, which will return 0 in case of an existing empty regular file or 1 otherwise:

-f FILE
    FILE exists and is a regular file
-s FILE
    FILE exists and has a size greater than zero
test -f file -a ! -s file && printf 'File exists and is empty.\n'

Or using a more common syntax:

[ -f file -a ! -s file ] && printf 'File exists and is empty.\n'
$ touch empty
$ printf '\n' >non_empty
$ test -f file -a ! -s empty && printf 'File exists and is empty.\n'
File exists and is empty.
$ test -f file -a ! -s non_empty && printf 'File exists and is empty.\n'
$ 

You could add a function to ~/.bashrc for convenience:

is_empty() { test -f file -a ! -s file && printf 'File exists and is empty.\n'; }

Or using a more common syntax:

is_empty() { [ -f file -a ! -s file ] && printf 'File exists and is empty.\n'; }
$ touch empty
$ printf '\n' >non_empty
$ is_empty empty 
File exists and is empty.
$ is_empty non_empty 
$ 
share|improve this answer
1  
Since -s is also false if the file doesn't exist, I'd suggest using -s on its own to test for a nonempty file, and [ -f "$1" -a ! -s "$1" ] to test specifically for an existing empty file, rather than ! -s on its own. – hobbs Mar 15 at 5:12
1  
(perhaps -e instead of -f, but it's usually only meaningful to talk about the size of regular files.) – hobbs Mar 15 at 5:13
    
@hobbs Yeah, looks better that way. Thanks. – kos Mar 15 at 8:01

You can also use stat:

$ touch file
$ stat --format '%F' file
regular empty file
$ echo 'a' > file
$ stat --format '%F' file
regular file
share|improve this answer

...or this:

find /dir/to/file -maxdepth 1 -name file_name -empty
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.