Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

How can I get the size of a file in a bash script?

How do I assign this to a bash variable so I can use it later?

share|improve this question

migrated from Jul 14 '11 at 0:59

This question came from our site for professional and enthusiast programmers.

8 Answers 8

up vote 36 down vote accepted

Your best bet:

stat --printf="%s" file.any

NOTE: see @chbrown answer below how to use stat in terminal on Mac OS X or

FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."
share|improve this answer
you know I'm just a newbie and I'm eager to learn... they say there's not such thing as dumb question; I honestly didn't know about stat. Thank you for your help. Appreciated. –  haunted85 Jul 13 '11 at 16:47
@haunted85 stat is the most straightforward way, assuming you're using Linux or Cygwin (stat isn't standard). wc -c as suggested by Eugéne is portable. –  Gilles Jul 14 '11 at 10:02
file_size_kb=`du -k "$filename" | cut -f1`

The problem with using stat is that it is a GNU (Linux) extension. du -k and cut -f1 are specified by POSIX and are therefore portable to any Unix system.

Solaris, for example, ships with bash but not with stat. So this is not entirely hypothetical.

ls has a similar problem in that the exact format of the output is not specified, so parsing its output cannot be done portably. du -h is also a GNU extension.

Stick to portable constructs where possible, and you will make somebody's life easier in the future. Maybe your own.

share|improve this answer
du doesn't give the size of the file, it gives an indication of how much space the file uses, which is subtly different (usually the size reported by du is the size of the file rounded up to the nearest number of blocks, where a block is typically 512B or 1kB or 4kB). –  Gilles Jul 14 '11 at 10:00

You could also use the "word count" command (wc):

wc -c $FILENAME| awk '{print $1}'

The problem with wc is that it'll add the filename and indent the file. If you would like to avoid chaining a full interpreted language just to get a file then:

wc -c $FILENAME| sed 's/ *\([^ ]*\)\ *.*/\1/'

should also work just fine...

or you could try:

wc -c < $FILENAME

which, with an assignment using back-quote semantics in Bourne Shell or the $() KSH/Bash command expansion as mentioned by Gilles below allows you to easily use the value you were seeking.

share|improve this answer
wc -c <"$FILENAME" gives the size with no other cruft, thus size=$(wc -c <"$FILENAME"). –  Gilles Jul 14 '11 at 9:58
Thanks Gilles, added and clarified. –  Eugéne Jun 12 '13 at 17:40

BSD's (Mac OS X's) stat has a different format argument flag, and different field specifiers. From man stat(1):

  • -f format: Display information using the specified format. See the FORMATS section for a description of valid formats.
  • ... the FORMATS section ...
  • z: The size of file in bytes.

So all together now:

stat -f%z myfile1.txt
share|improve this answer

ls -l filename will give you lots of information about a file, including its file size, permissions and owner.

The file size in the fifth column, and is displayed in bytes. In the example below, the filesize is just under 2KB:

-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php

Edit: This is apparently not as reliable as the stat command.

share|improve this answer
I think both ls -l and stat command give reliable size information. I did not find any reference to the contrary. ls -s will give size in number of blocks. –  dabest1 Dec 31 '12 at 22:23
@dabest1 it's not reliable in a sense that in another unix, their output can be different (and in some unixes it is). –  Eugene Bujak Oct 2 '14 at 14:39

This script combines many ways to calculate the file size:

  du --apparent-size --block-size=1 "$file" 2>/dev/null ||
  gdu --apparent-size --block-size=1 "$file" 2>/dev/null ||
  find "$file" -printf "%s" 2>/dev/null ||
  gfind "$file" -printf "%s" 2>/dev/null ||
  stat --printf="%s" "$file" 2>/dev/null ||
  stat -f%z "$file" 2>/dev/null ||
  wc -c <"$file" 2>/dev/null
) | awk '{print $1}'

The script works on many Unix systems including Linux, BSD, OSX, Solaris, SunOS, etc.

The file size is show in bytes. It is the apparent size, which is the bytes the file uses on a typical disk, without special compression, or special sparse areas, or unallocated blocks, etc.

This script has a production version with more help and more options here:

share|improve this answer

du filename will tell you disk usage in bytes.

I prefer du -h filename, which gives you the size in a human readable format.

share|improve this answer
that or stat -c "%s" ;) –  c00kiemon5ter Jul 13 '11 at 16:29
This flavor of du prints out size in blocks of 1024 bytes, not a simple count of bytes. –  Peter Lyons Sep 17 at 5:10

I like the wc option myself. Paired with 'bc,' you can get decimals to as many places as you please.

I was looking to improve a script I had that awk'ed out the 'file size' column of an 'ls -alh' command. I didn't want just integer file sizes, and two decimals seemed to suit, so after reading this discussion, I came up with the code below.

I suggest breaking the line at the semicolons if you include this in a script.

file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"

My script is called gpfl, for "get picture file length." I use it after doing a mogrify on a file in imagemagick, before opening or re-loading a picture in a GUI jpeg viewer.

I don't know how this rates as an "answer," as it borrows much from what's already been offered and discussed. So I'll leave it there.


share|improve this answer
I would prefer using "stat" or "ls". Typically I don't like using "wc" to get file sizes because it physically reads the entire file. If you have a lot of files, or particularly large files, this can take a lot of time. But your solution is creative...+1. –  Kevin Fegan Dec 9 '13 at 19:18
I agree with notion of using "stat" over "wc" for filesize, however if you use "wc -c", no data will be read; instead lseek will be used to figure out the number of bytes in a file. –  bbaja42 Dec 14 '14 at 14:38

Your Answer


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.