F2 is a cross-platform command-line tool for batch renaming files and directories quickly and safely. Written in Go!

Overview

f2

Github Actions made-with-Go GoReportCard Go.mod version LICENCE Latest release

F2 - Command-line batch renaming tool

F2 is a cross-platform command-line tool for batch renaming files and directories quickly and safely. Written in Go!

F2 in action on Ubuntu Linux

Installation

F2 is written in Go, so you can install it through go install (requires Go 1.16 or later):

$ go install github.com/ayoisaiah/f2/cmd/[email protected]

📦 NPM package

You can also install F2 via its npm package:

With npm:

$ npm i @ayoisaiah/f2 -g

With yarn:

$ yarn global add @ayoisaiah/f2

Other installation methods are available here.

💥 Why should you use F2?

  • F2 helps you organise your filesystem through batch renaming so that your files and directories can have a consistent naming scheme.
  • It offers a comprehensive set of renaming options, and scales well from trivial string replacements to more complex operations involving regular expressions.
  • F2 prioritises correctness and safety by ensuring that a renaming operation does not result in conflicts or errors. It runs several validations before carrying out a renaming operation, and provides an easy way to automatically fix any detected conflicts.
  • F2 supports all the standard renaming recipes including (but not limited to) string replacement, insertion of text as a prefix, suffix or other position in the file name, stripping a set of characters, changing the case of a set of letters, using auto incrementing numbers, swapping parts of the file name, e.t.c.
  • F2 provides several built-in variables for added flexibility in the renaming process. These variables are based on file attributes such as Exif information for images, and ID3 tags for audio files. F2 also supports utilising tags from the popular exiftool which should cover most use cases.
  • F2 is very fast and won't waste your time. See benchmarks.
  • F2 allows you to revert any renaming operation performed with the program. This means you don't have to worry about making a mistake because you can always get back to the previous state without breaking a sweat.
  • F2 has good test coverage with equal attention paid to all supported platforms (Linux, Windows and macOS).
  • F2 is well documented so that you won't have to scratch your head while figuring out what you can do with it. Lots of realistic examples are provided to aid comprehension.

Main features

  • Safe and transparent. F2 uses a dry run mode by default so you can review the exact changes that will be made to your filesystem before making them.
  • Cross-platform with full support for Linux, macOS, and Windows. It also runs on less commonly-used platforms, like Termux (Android).
  • Extremely fast, even when working with a large amount of files.
  • Supports the chaining of several consecutive renaming operations before a final output is produced.
  • Automatically detects potential conflicts such as file collisions, or overrides and reports them to you.
  • Provides several built-in variables for the easier renaming of certain file types.
  • Provides easy access to all ~25,000 tags in exiftool for maximum flexibility in renaming.
  • Supports find and replace using regular expressions, including capture groups.
  • Ignores hidden directories and files by default.
  • Respects the NO_COLOR environmental variable.
  • Supports limiting the number of replaced matches, and you can start from the beginning or end of the file name.
  • Supports recursive renaming for both files and directories.
  • Supports renaming only files, or only directories, or both.
  • Supports using an ascending integer for renaming (e.g 001, 002, 003, e.t.c.), and it can be formatted in several ways.
  • Supports undoing the last renaming operation in case of mistakes or errors.
  • Supports renaming from a CSV file.
  • Extensive documentation and examples for each option that is provided.

💻 Screenshots

Screenshot of F2 in action on Linux

F2 can utilise exif attributes from a variety of image formats

F2 can utilise ID3 attributes to organise music files

📃 Documentation

Visit the wiki page to view usage examples and learn about all the renaming operations that can be achieved with F2.

🔥 Benchmarks

Environment

  • OS: Ubuntu 20.04.2 LTS on Windows 10 x86_64
  • CPU: Intel i7-7560U (4) @ 2.400GHz
  • Kernel: 4.19.128-microsoft-standard

Renaming 10,000 MP3 files using their ID3 attributes (~1.6 seconds):

$ hyperfine --warmup 3 'f2 -f ".*" -r "{{id3.artist}}_{{id3.album}}_{{id3.track}}_{{r} }.mp3" -x'
Benchmark #1: f2 -f ".*" -r "{{id3.artist}}_{{id3.album}}_{{id3.track}}_{{r}}.mp3" -x
  Time (mean ± σ):      1.691 s ±  0.031 s    [User: 1.326 s, System: 0.744 s]
  Range (min … max):    1.634 s …  1.736 s    10 runs

Renaming 100,000 files using a random string and an auto incrementing integer (~5 seconds):

$ hyperfine --warmup 3 'f2 -f ".*" -r "{{r}}_%03d" -x'
Benchmark #1: f2 -f ".*" -r "{{r}}_%03d" -x
  Time (mean ± σ):      4.938 s ±  0.328 s    [User: 2.792 s, System: 2.770 s]
  Range (min … max):    4.421 s …  5.474 s    10 runs

Renaming 100,000 JPEG files using their Exif attributes (~30 seconds):

$ hyperfine --warmup 3 'f2 -f ".*" -r "{{x.make}}_{{x.model}}_{{x.iso}}_{{x.wh}}_{{r}}_%03d.jpg" -x'
Benchmark #1: f2 -f ".*" -r "{{x.make}}_{{x.model}}_{{x.iso}}_{{x.wh}}_{{r}}_%03d.jpg" -x
  Time (mean ± σ):     31.143 s ±  1.691 s    [User: 34.792 s, System: 4.779 s]
  Range (min … max):   29.317 s … 33.355 s    10 runs

Windows

Renaming 10,000 MP3 files with an auto incrementing integer through native PowerShell commands (~30 seconds):

$ Measure-Command { Get-ChildItem *.mp3 | ForEach-Object -Begin { $count = 1 } -Process { Rename-Item $_ -NewName "music_$count.mp3"; $count++ } }
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 29
Milliseconds      : 582
Ticks             : 295824810
TotalDays         : 0.000342389826388889
TotalHours        : 0.00821735583333333
TotalMinutes      : 0.49304135
TotalSeconds      : 29.582481
TotalMilliseconds : 29582.481

Renaming 10,000 MP3 files with an auto incrementing integer through F2 (~12 seconds):

$ Measure-Command { f2 -f ".*" -r "audio_%03d.mp3" -x }
Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 11
Milliseconds      : 634
Ticks             : 116342215
TotalDays         : 0.000134655341435185
TotalHours        : 0.00323172819444444
TotalMinutes      : 0.193903691666667
TotalSeconds      : 11.6342215
TotalMilliseconds : 11634.2215

🤝 Contribute

Bug reports and feature requests are much welcome! Please open an issue before creating a pull request.

Licence

Created by Ayooluwa Isaiah and released under the terms of the MIT Licence.

Issues
  • [Feature Request] Add an option that allows passing a list of files as argument

    [Feature Request] Add an option that allows passing a list of files as argument

    In some cases we need to batch rename some files which don't share any similarities in the file names. It would be a pain in the ass to write a RE to match all of them at the same time. It f2 could take a list of files (directly in the command line or as a list file ) as argument, it would be much easier. Thanks!

    enhancement 
    opened by nightson 14
  • Leading zeros

    Leading zeros

    I'm using

    f2 -f '(\w+) ((\d+)).(\w+)' -r '$1-$2.$3'

    and get

    | ORIGINAL | RENAMED | STATUS | | ************************************************ | | 1528655011 (1).jpg | 1528655011-1.jpg | ok | | 1528655011 (10).jpg | 1528655011-10.jpg | ok |

    but I want for $2 leading zeros and 3 digits.

    How I have to do it?

    opened by jsteltner 4
  • [bug] error when double dots

    [bug] error when double dots ".." in sub-folder (of dst path)

    I'm using f2 to group lots of files into sub-folders based on part of their names, via regex. When renameing is something like from src /root/title [artist_name_with..].mp4 to dst /root/artist_name_with../title [artist_name_with..].mp4, it throws an error occurred while renaming. Could only guess but seems like the double dots .. in the sub-folder name artist_name_with.. is the cause.

    OS is Windows 10

    windows 
    opened by mo-han 4
  • "-e" option considers the last period in directory name as extension separator

    For example, if I have directory test.dir.period nested inside test directory, then running f2 -ed -f '\.' -r ' ' test returns this:

    +----------------------+----------------------+--------+
    |        INPUT         |        OUTPUT        | STATUS |
    +----------------------+----------------------+--------+
    | test/test.dir.period | test/test dir.period | ok     |
    +----------------------+----------------------+--------+
    

    And if I try to match the "extension" of the directory by running f2 -ed -f 'period' -r 'full stop' test: INFO Failed to match any files

    Version: 1.7.2 OS: Arch Linux

    opened by nevermarine 3
  • [question] how does f2 distinguish regex from simple text?

    [question] how does f2 distinguish regex from simple text?

    there's neither cli option to toggle regex, nor special format in text for -f -r options, to tell if the text is regex or not in case the text is both acceptable as regex or literal, how to ensure f2 work correctly?

    enhancement 
    opened by mo-han 3
  • Installation is not supported for this architecture: arm64

    Installation is not supported for this architecture: arm64

    I am using a Mac Silicon Mx chip. I couldn't install F2 please help

    $ npm i @ayoisaiah/f2 -g                                                                                                                                                                                                                         ~
    npm WARN deprecated [email protected]: this library is no longer supported
    npm WARN deprecated [email protected]: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
    npm WARN deprecated [email protected]: request has been deprecated, see https://github.com/request/request/issues/3142
    npm WARN deprecated [email protected]: This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.
    npm ERR! code 1
    npm ERR! path /opt/homebrew/lib/node_modules/@ayoisaiah/f2
    npm ERR! command failed
    npm ERR! command sh -c go-npm install
    npm ERR! Installation is not supported for this architecture: arm64
    npm ERR! Invalid inputs
    
    npm ERR! A complete log of this run can be found in:
    
    opened by sadhasivam 2
  • f2 phones home to Microsoft leaking my IP as an f2 user without consent when I run `f2 --version`

    f2 phones home to Microsoft leaking my IP as an f2 user without consent when I run `f2 --version`

    Behavior reproduced in F2 version v1.7.2:

    https://github.com/ayoisaiah/f2/blob/134ae1ec23ef74c8248c7b4b09035ca3d53a6d49/src/app.go#L149

    Steps to reproduce:

    1. Run f2 --version.

    Observed behavior:

    F2 phones home to Microsoft without consent, leaking my IP to Microsoft as a user of F2 (enabling tracking):

    Screen Shot 2022-02-01 at 21 56 20

    Expected behavior:

    The software would ask opt-in permission before leaking my usage activity and IP to giant multinationals.

    opened by sneak 2
  • fails to run on long paths in windows.

    fails to run on long paths in windows.

    Create this Dir: C:\My Drive\temploweirdo.com\5.Data Structures and Algorithms\1. Asymptotic Analysis and Insertion Sort, Merge Sort\2.Sorting & Searching why bother with these simple tasks Say a.

    Create this file in a: 1. Sorting & Searching- why bother with these simple tasks- - Data Structure & Algorithms - Part-2.mp4

    Now running f2 -f '.*' in a, fails with Path Not Specified Error.

    Cause of error: https://github.com/ayoisaiah/f2/blob/822837779d13a704770a78080507ebf0d6497759/src/operation_windows.go#L13-L30

    Specifically, syscall.GetFileAttributes(), most probably because of long path names.


    Possible Solutions: Appending \\?\ in front of an absolute path. (But you seem to use relative path for baseDir)

    I'm not sure though, please check once again. Please make sure that it works with long file names and paths.

    Thank you.

    bug windows 
    opened by nilsocket 2
  • RFE: Avoid cluttering $HOME, move config files/data to their appropriate place.

    RFE: Avoid cluttering $HOME, move config files/data to their appropriate place.

    Short description: f2 writes to $HOME/.f2

    What is wrong with this? If all programs would write to $HOME, one would end up with $HOME full of dot files/dirs. This not only leads to cutter, but makes it difficult for backup. There are also folks who manage their $HOME or part(s) of it with git. So if apps write non important stuff directly to $HOME, you can imagine how many changes git would report. One would also backup this stuff. Their exists a standard that defines where an application should save {config, temporary, cache,...} files. For more information have a look at XDG spec.

    Solution: https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html

    Go implementations of the the spec (random): https://github.com/adrg/xdg https://github.com/rkoesters/xdg

    F2 version v1.6.7

    enhancement 
    opened by devwatchdog 2
  • issue on New feature (from 1.6.4 multiple renaming in the same command line

    issue on New feature (from 1.6.4 multiple renaming in the same command line

    Hello

    on 1.6.4 release the new feature, seems to not work (or i'm badly trying to use it :) )

    You can now chain several renaming operations by specifying the --find and --replace flags multiple times.

    in the below example i'm trying to rename all cbr/cbz files to rar/zip, but the command result on the first -find -replace in the command line

    C:\Temp\test>dir
     Le volume dans le lecteur C n’a pas de nom.
     Le numéro de série du volume est CCB8-8D6F
    
     Répertoire de C:\Temp\test
    
    29/05/2021  17:34                 0 No Pressure (2021) S01.E01.2160p.mp4
    29/05/2021  17:28                 0 test1.cbr
    29/05/2021  17:28                 0 test2.cbz
    
    C:\Temp\test>D:\Workspace\Dev\optimize-file\Modules\f2\f2.exe -f ".cbz" -r ".zip" -f ".cbr" -r ".rar" -i -s C:\Temp\test\
    +------------------------+------------------------+--------+
    |         INPUT          |         OUTPUT         | STATUS |
    +------------------------+------------------------+--------+
    | C:\Temp\test\test2.cbz | C:\Temp\test\test2.zip | ok     |
    +------------------------+------------------------+--------+
    Append the -x flag to apply the above changes
    
    C:\Temp\test>D:\Workspace\Dev\optimize-file\Modules\f2\f2.exe --find ".cbr" --replace ".rar" --find ".cbz" --replace ".zip" -i -s C:\Temp\test\
    +------------------------+------------------------+--------+
    |         INPUT          |         OUTPUT         | STATUS |
    +------------------------+------------------------+--------+
    | C:\Temp\test\test1.cbr | C:\Temp\test\test1.rar | ok     |
    +------------------------+------------------------+--------+
    Append the -x flag to apply the above changes
    

    tested with 1.6.5 and 1.6.4 OS: windows 10 20H2

    any suggestion on the right way to use it?

    many thanks Tonic8

    opened by Tonic8 2
  • [bug] auto make directory failed (windows os)

    [bug] auto make directory failed (windows os)

    • a file named as video file from internet [youtube][id][uploader] - part 2.mp4 in R:\ (windows drive root path)
    • i'd like to rename/move it into a sub folder named [uploader]
    • the f2 command used was f2 -f "^(.*(\[.+?\]).*?)$" -r "$2\$1" -x R:\
    • f2 error was An error occurred while renaming 'R:\video file from internet [youtube][id][uploader] - part 2.mp4' to 'R:\[uploader]\video file from internet [youtube][id][uploader] - part 2.mp4'
    • it did try to rename it with prefix path of parent R:\[uploader]\, but this sub folder/directory wasn't there

    not sure if it's windows os specific bug maybe the windows path sep backslash \ is the cause?

    bug windows 
    opened by mo-han 2
Releases(v1.8.0)
Owner
Ayooluwa
Software Developer
Ayooluwa
Rclone ("rsync for cloud storage") is a command line program to sync files and directories to and from different cloud storage providers.

Rclone ("rsync for cloud storage") is a command line program to sync files and directories to and from different cloud storage providers.

rclone 33.4k Jun 24, 2022
Rclone ("rsync for cloud storage") is a command-line program to sync files and directories to and from different cloud storage providers.

Website | Documentation | Download | Contributing | Changelog | Installation | Forum Rclone Rclone ("rsync for cloud storage") is a command-line progr

null 0 Nov 5, 2021
A simple tool which you can use to move through your directories from the command line

Fe What is Fe ? Fe is a simple tool which you can use to move through your direc

Pranav Baburaj 8 Jan 1, 2022
cross platform command line tool to list, notify and book vaccine using cowin API

Command line tool to List and Book Vaccine cowin-cli is a simple cli tool to book vaccines and list centers using the COWIN API. It also supports auto

Anoop S 35 Mar 7, 2022
A command line tool that builds and (re)starts your web application everytime you save a Go or template fileA command line tool that builds and (re)starts your web application everytime you save a Go or template file

# Fresh Fresh is a command line tool that builds and (re)starts your web application everytime you save a Go or template file. If the web framework yo

null 0 Nov 22, 2021
Watcher - A simple command line app to watch files in a directory for changes and run a command when files change!

Watcher - Develop your programs easily Watcher watches all the files present in the directory it is run from of the directory that is specified while

Geet Sethi 1 Mar 27, 2022
textnote is a command line tool for quickly creating and managing daily plain text notes.

textnote is a command line tool for quickly creating and managing daily plain text notes. It is designed for ease of use to encourage the practice of daily, organized note taking. textnote intentionally facilitates only the management (creation, opening, organizing, and consolidated archiving) of notes, following the philosophy that notes are best written in a text editor and not via a CLI.

Daniel Kaslovsky 156 Jun 7, 2022
A command line tool for quickly converting Unix timestamps to human readable form.

stamp A command line tool to quickly format a Unix timestamp in a human-readable form. Installation Go is required to build this software. To just bui

Ricco Førgaard 1 Oct 30, 2021
An open-source GitLab command line tool bringing GitLab's cool features to your command line

GLab is an open source GitLab CLI tool bringing GitLab to your terminal next to where you are already working with git and your code without switching

Clement Sam 2k Jun 25, 2022
A command line tool to prompt for a value to be included in another command line.

readval is a command line tool which is designed for one specific purpose—to prompt for a value to be included in another command line. readval prints

Venky 0 Dec 22, 2021
tmux-wormhole - download files and directories with tmux!

tmux-wormhole Use tmux and magic wormhole to get things from your remote computer to your tmux. If tmux has DISPLAY set, open the file locally! Demo U

Graham Clark 41 Jun 29, 2022
:zap: boilerplate template manager that generates files or directories from template repositories

Boilr Are you doing the same steps over and over again every time you start a new programming project? Boilr is here to help you create projects from

Tamer Tas 1.5k Jun 22, 2022
sttr is command line software that allows you to quickly run various transformation operations on the string.

sttr is command line software that allows you to quickly run various transformation operations on the string.

Abhimanyu Sharma 60 Sep 21, 2021
From the command line, quickly explore data from a CSV file.

shallow-explore From the command line, quickly explore data from a CSV file. shallow-explore is a Golang backed command-line tool for iterating over c

Thomas Mickley-Doyle 29 Jun 10, 2022
🧹 Safely clean up your local branches

gh poi A gh extension for deleting merged local branches. This extension checks the state of remote pull requests, so it works even when you "Squash a

Seito Tanaka 90 Jun 28, 2022
mlp is a comman line tool responsible for creating, updating and deleting kubernetes resources based on files generated by Mia-Platform Console.

mlp is a comman line tool responsible for creating, updating and deleting kubernetes resources based on files generated by Mia-Platform Console.

Mia-Platform 5 Apr 28, 2022
fofax is a fofa query tool written in go, positioned as a command-line tool and characterized by simplicity and speed.

fofaX 0x00 Introduction fofax is a fofa query tool written in go, positioned as

null 395 Jun 23, 2022
Simple and easy to use command line application written in Go for cleaning unnecessary XCode files.

xcclear Say hello to a few extra gigabytes of space on your Mac with xcclear, a simple and easy to use command line application written in Go for clea

null 57 Jun 28, 2022
Command-line tool to load csv and excel (xlsx) files and run sql commands

csv-sql supports loading and saving results as CSV and XLSX files with data processing with SQLite compatible sql commands including joins.

Dhamith Hewamullage 22 May 6, 2022