Linux command to remove a file only if it's a certain size?

Hi I’m wondering if there’s a Linux command that will:

  1. Delete file A if file B is 1345 bytes.
  2. Delete file B only if it is 1345 bytes. If it’s not that size, just leave it alone.

The only caveat is it it can’t be a shell script. It can be series of commands typed on the command line, but I’m executing these lines from a program that has variables for the file name, and I can’t easily pass the variables to a shell script but I can pass them to a system command line.

Hopefully that makes sense…

In bash:



if test $(stat -c%s file_b) -eq 1345; then rm file_a; rm file_b; fi;


Note that this relies on you have the GNU version of stat, so it won’t work on most flavors of BSD.

However, given that this is happening inside a program of some sort, can’t you use whatever your programming language provides to determine the size of a file on disk?

How about;

find . -size 1345c | xargs rm

Oops, didn’t read the question carefully;

find . -size 1345c -name fileb -exec rm ‘{}’ filea ;

It sounds to me like there’s a better way to solve the underlying puzzle here. Can you tell us a bit more about the context surrounding this request?

This doesn’t make sense to me. Whether you invoke “/bin/ls file” or “/home/aaelghat/bin/myscript file” you’re passing an argument “to a system command line”.

Are you writing this program in C or C++? If so, you would do better to use the stat() and unlink() system calls. Do man 2 stat and man 2 unlink on the command line to see more information about them.

Hi, thanks for the replies. Here’s the full background on this and what I’m trying to do…

I’m using an open source PBX system called Asterisk, running on a Linux CentOS box. Asterisk uses a “dialplan” proprietary language to let you control what happens when someone makes a call. One of the commands is called Systemwhich lets you run a command line argument.

What I’m doing is using that function to call SoX (an open Source audio editor) to clean up voicemail messages that are left. I’m basically using SoX functions to delete silence and hangup clicks from the ends of the voicemail and amplify the files. In the code below, the variable ${VM_MESSAGEFILE} is the location on the server of the voicemail file. The lines of code I use are:


exten => exit-SUCCESS,n,System(sox ${VM_MESSAGEFILE}.wav ${VM_MESSAGEFILE}-old.wav)
exten => exit-SUCCESS,n,System(sox ${VM_MESSAGEFILE}-old.wav ${VM_MESSAGEFILE}.wav compand 0.3\,1 6:-70\,-60\,-20 -5 -90 0.2 vad reverse vad reverse)
exten => exit-SUCCESS,n,System(rm ${VM_MESSAGEFILE}-old.wav)


OK, great. The code works perfectly, but here’s the problem. Let’s say someone leaves a voicemail message of just silence. When SoX runs, it will delete out the silence but it leaves a stub of a WAV file. That file is always a certain fixed size (44 bytes to be exact) and I want to delete it because it is unplayable anyway. There are also ancillary files associated with that same message that I want to delete that have the same name, but different extensions, and I want to delete those documents as well.

So, the logic is kind of like, if msg0032.wav is 44 bytes, delete that file along with msg0032.WAV and msg0032.txt

The reason I was shying away from a shell script is that the variable ${VM_MESSAGEFILE} is coming from the asterisk pbx system, and I’m not sure if I can pass it to an external shell script.

I haven’t tested it yet, but it looks like friedo’s suggestion might work? Hopefully this all makes sense…

Well, this appears to indicate that you can stat a file in Asterisk.

OK, I hate to be dense (but when it comes to Linux I am).

Thanks for the link Punoqllads, but how do I use that in a form of what friedo wrote to delete the files. What I did, was use friedo’s command at the command line (substiting the names of the files), and that worked perfectly. So my OS does understand stat.

But when I embedded it in Asterisk in the form of


exten => exit-SUCCESS,n,System(if test $(stat -c%s ${VM_MESSAGEFILE}.wav) -eq 44; then rm ${VM_MESSAGEFILE}.wav; rm ${VM_MESSAGEFILE}.txt; rm ${VM_MESSAGEFILE}.WAV; fi;)


It got interpreted as…


if test $(stat -c%s /var/spool/asterisk/voicemail/default/70312/INBOX/msg0040.wav

so I think the right parenthesis screwed it up…when run against a 44 byte file nothing got deleted so it didn’t work. What would the format be if I used the Asterisk stat command directly?

Thanks!!!

I’m guessing the Asterisk system function does not start an actual shell to execute the command (makes sense.) You could hack around it by putting your stuff in a shell script and passing your variables to it, but I think a better way would be to use the Asterisk stat and system rm commands.

I’m not familiar with Asterisk syntax at all, but it looks like you may be able to use the ExecIf function like this:



exten => exit-SUCCESS,n,(ExecIf(STAT(s, ${VM_MESSAGEFILE}.wav)=44?rm ${VM_MESSAGEFILE})


…or something like that.

I don’t completely grok Asterisk’s syntax, but it would probably be something like:

ExecIf(Stat(s, {VM_MESSAGEFILE}.wav) = 44 ? System(rm {VM_MESSAGFILE}.wav))

assuming you’re using version 1.6.