Forum: Ruby One liner for filenames

Posted by Peter Bailey (peterbailey)
on 2013-01-08 21:48
Hello,
Can someone help me to write a Ruby one-liner to remove all the files
except one in a list of files? I have a list of pages of an original
PDF. Each page has been converted to a PNG file. They're each numbered
with an underscore and a number at their end.

filename_1.png
filename_2.png
filename_3.png
...

I need to basically delete all of the files except for the first one,
the one with the "_1" suffix at the end. Can I do that wiith a
one-liner?

Thanks,
Peter
Posted by Damián M. González (igorjorobus)
on 2013-01-08 23:04
Peter Bailey wrote in post #1091502:
> Hello,
> Can someone help me to write a Ruby one-liner to remove all the files
> except one in a list of files? I have a list of pages of an original
> PDF. Each page has been converted to a PNG file. They're each numbered
> with an underscore and a number at their end.
>
> filename_1.png
> filename_2.png
> filename_3.png
> ...
>
> I need to basically delete all of the files except for the first one,
> the one with the "_1" suffix at the end. Can I do that wiith a
> one-liner?
>
> Thanks,
> Peter

 Test this:

ruby -e "Dir.foreach('C:/Directory_with_png/') {|file| File.delete(file) 
unless (file.==('.')) || (file.==('..') || (file.==('filename_1.png'))"

 Kind regards.
Posted by Kim Pedersen (Guest)
on 2013-01-09 00:29
(Received via mailing list)
>
> I need to basically delete all of the files except for the first one,
> the one with the "_1" suffix at the end. Can I do that wiith a
> one-liner?
>
> Thanks,
> Peter
>

Hi,

This should work

ruby -e "Dir.glob('*_*.png')[1..-1].each { |fn| File.delete fn}"

Best regards
Kim
Posted by Peter Bailey (peterbailey)
on 2013-01-09 13:08
Kim Pedersen wrote in post #1091524:
>>
>> I need to basically delete all of the files except for the first one,
>> the one with the "_1" suffix at the end. Can I do that wiith a
>> one-liner?
>>
>> Thanks,
>> Peter
>>
>
> Hi,
>
> This should work
>
> ruby -e "Dir.glob('*_*.png')[1..-1].each { |fn| File.delete fn}"
>
> Best regards
> Kim

Thank you very much, Kim. It's a big help.
Cheers.
Posted by Robert Klemme (robert_k78)
on 2013-01-09 16:10
(Received via mailing list)
On Tue, Jan 8, 2013 at 9:48 PM, Peter Bailey <lists@ruby-forum.com> 
wrote:
>
> I need to basically delete all of the files except for the first one,
> the one with the "_1" suffix at the end. Can I do that wiith a
> one-liner?

ruby -r pathname -e 'Pathname.glob("*[^1].png").each(&:delete)'

Kind regards

robert
Posted by Peter Bailey (peterbailey)
on 2013-01-09 16:13
Robert Klemme wrote in post #1091597:
> On Tue, Jan 8, 2013 at 9:48 PM, Peter Bailey <lists@ruby-forum.com>
> wrote:
>>
>> I need to basically delete all of the files except for the first one,
>> the one with the "_1" suffix at the end. Can I do that wiith a
>> one-liner?
>
> ruby -r pathname -e 'Pathname.glob("*[^1].png").each(&:delete)'
>
> Kind regards
>
> robert

Thanks, Robert.
Posted by Peter Bailey (peterbailey)
on 2013-01-09 16:15
Kim Pedersen wrote in post #1091524:
>>
>> I need to basically delete all of the files except for the first one,
>> the one with the "_1" suffix at the end. Can I do that wiith a
>> one-liner?
>>
>> Thanks,
>> Peter
>>
>
> Hi,
>
> This should work
>
> ruby -e "Dir.glob('*_*.png')[1..-1].each { |fn| File.delete fn}"
>
> Best regards
> Kim

Kim,
I'd like to ask you about [1..-1]. I've never seen that before. Is that 
what's selecting all the files except the first one?
-Peter
Posted by Hans Mackowiak (hanmac)
on 2013-01-09 16:23
about Array#[]:

[1,2,3,4,5][1..-1] #=> [2,3,4,5]

about Dir.glob():

you need to be careful, because the array is unsorted
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2013-01-09 16:49
(Received via mailing list)
On Wed, Jan 9, 2013 at 4:09 PM, Robert Klemme
<shortcutter@googlemail.com> wrote:
>> ...
>>
>> I need to basically delete all of the files except for the first one,
>> the one with the "_1" suffix at the end. Can I do that wiith a
>> one-liner?
>
> ruby -r pathname -e 'Pathname.glob("*[^1].png").each(&:delete)'

Careful, as this skips also filename_11.png, filename_21.png, etc.
Building on this:

ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'

Jesus.
Posted by Robert Klemme (robert_k78)
on 2013-01-09 16:56
(Received via mailing list)
On Wed, Jan 9, 2013 at 4:48 PM, Jess Gabriel y Galn
<jgabrielygalan@gmail.com> wrote:
> On Wed, Jan 9, 2013 at 4:09 PM, Robert Klemme
> <shortcutter@googlemail.com> wrote:

>> ruby -r pathname -e 'Pathname.glob("*[^1].png").each(&:delete)'
>
> Careful, as this skips also filename_11.png, filename_21.png, etc.
> Building on this:
>
> ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'

+1  I wasn't aware that there could be larger numbers. Thank you for
the correction!

Cheers

robert
Posted by Peter Bailey (peterbailey)
on 2013-01-09 17:00
"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post 
#1091607:
> On Wed, Jan 9, 2013 at 4:09 PM, Robert Klemme
> <shortcutter@googlemail.com> wrote:
>>> ...
>>>
>>> I need to basically delete all of the files except for the first one,
>>> the one with the "_1" suffix at the end. Can I do that wiith a
>>> one-liner?
>>
>> ruby -r pathname -e 'Pathname.glob("*[^1].png").each(&:delete)'
>
> Careful, as this skips also filename_11.png, filename_21.png, etc.
> Building on this:
>
> ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'
>
> Jesus.

Excellent. Thanks. Hans is right, though. Dir.glob is unsorted. Is that 
a problem here?
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2013-01-09 17:14
(Received via mailing list)
On Wed, Jan 9, 2013 at 5:00 PM, Peter Bailey <lists@ruby-forum.com> 
wrote:
>>> ruby -r pathname -e 'Pathname.glob("*[^1].png").each(&:delete)'
>>
>> Careful, as this skips also filename_11.png, filename_21.png, etc.
>> Building on this:
>>
>> ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'
>>
>> Jesus.
>
> Excellent. Thanks. Hans is right, though. Dir.glob is unsorted. Is that
> a problem here?

No, because here we are using the glob facility to do all the
filtering. In the other solution, there was the array returned from
the glob that was being filtered, and so the order was important for
the solution that removed the first entry in the array.

Jesus.
Posted by Peter Bailey (peterbailey)
on 2013-01-09 17:23
"Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post 
#1091613:
> On Wed, Jan 9, 2013 at 5:00 PM, Peter Bailey <lists@ruby-forum.com>
> wrote:
>>>> ruby -r pathname -e 'Pathname.glob("*[^1].png").each(&:delete)'
>>>
>>> Careful, as this skips also filename_11.png, filename_21.png, etc.
>>> Building on this:
>>>
>>> ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'
>>>
>>> Jesus.
>>
>> Excellent. Thanks. Hans is right, though. Dir.glob is unsorted. Is that
>> a problem here?
>
> No, because here we are using the glob facility to do all the
> filtering. In the other solution, there was the array returned from
> the glob that was being filtered, and so the order was important for
> the solution that removed the first entry in the array.
>
> Jesus.

Beautiful. Thanks a lot.
Posted by Peter Bailey (peterbailey)
on 2013-01-10 01:08
Peter Bailey wrote in post #1091614:
> "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> wrote in post
> #1091613:
>> On Wed, Jan 9, 2013 at 5:00 PM, Peter Bailey <lists@ruby-forum.com>
>> wrote:
>>>>> ruby -r pathname -e 'Pathname.glob("*[^1].png").each(&:delete)'
>>>>
>>>> Careful, as this skips also filename_11.png, filename_21.png, etc.
>>>> Building on this:
>>>>
>>>> ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'
>>>>
>>>> Jesus.
>>>
>>> Excellent. Thanks. Hans is right, though. Dir.glob is unsorted. Is that
>>> a problem here?
>>
>> No, because here we are using the glob facility to do all the
>> filtering. In the other solution, there was the array returned from
>> the glob that was being filtered, and so the order was important for
>> the solution that removed the first entry in the array.
>>
>> Jesus.
>
> Beautiful. Thanks a lot.

This is what I'm getting. I'm sure i'm missing something simple.

ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'
-e:1: syntax error, unexpected $end, expecting ')'
Posted by Robert Klemme (robert_k78)
on 2013-01-10 08:12
(Received via mailing list)
On Thu, Jan 10, 2013 at 1:09 AM, Peter Bailey <lists@ruby-forum.com> 
wrote:
>>>>> ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'
>>>
>>> Jesus.
>>
>> Beautiful. Thanks a lot.
>
> This is what I'm getting. I'm sure i'm missing something simple.
>
> ruby -r pathname -e 'Pathname.glob("*_{[^1],??}.png").each(&:delete)'
> -e:1: syntax error, unexpected $end, expecting ')'

Any chance you are using Ruby 1.8*?  If so I suggest to upgrade to 1.9*.

Kind regards

robert
Posted by Brian D. B. (briand_b)
on 2013-01-10 10:24
(Received via mailing list)
On 01/08/2013 05:04 PM, Damián M. González wrote:
>> ...
> ruby -e "Dir.foreach('C:/Directory_with_png/') {|file| File.delete(file)
> unless (file.==('.')) || (file.==('..') || (file.==('filename_1.png'))"
>
>  Kind regards.
>

There's certainly many ways to do this, but globing will ignore the dot
dirs, and is a bit shorter.
File.delete *Dir['*.png'].reject {|f| f =~ /_1\.png$/ }
Posted by Peter Bailey (peterbailey)
on 2013-01-10 12:58
Brian D. B. wrote in post #1091712:
> On 01/08/2013 05:04 PM, Damián M. González wrote:
>>> ...
>> ruby -e "Dir.foreach('C:/Directory_with_png/') {|file| File.delete(file)
>> unless (file.==('.')) || (file.==('..') || (file.==('filename_1.png'))"
>>
>>  Kind regards.
>>
>
> There's certainly many ways to do this, but globing will ignore the dot
> dirs, and is a bit shorter.
> File.delete *Dir['*.png'].reject {|f| f =~ /_1\.png$/ }

Thanks, Brian. But, even preceding this with "ruby -e" gives me nothing. 
Should I make this part of a script instead of it being a one-liner?
Posted by Brian D. B. (briand_b)
on 2013-01-11 11:12
(Received via mailing list)
On 01/10/2013 06:58 AM, Peter Bailey wrote:
>> dirs, and is a bit shorter.
>> File.delete *Dir['*.png'].reject {|f| f =~ /_1\.png$/ }
>
> Thanks, Brian. But, even preceding this with "ruby -e" gives me nothing.
> Should I make this part of a script instead of it being a one-liner?
>

That's odd... Works for me under 1.8.7, 1.9.2 and 1.9.3.
ruby -e "File.delete *Dir['*.png'].reject {|f| f=~ /_1\.png$/ }"
There will be no output. It will just delete the files.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.