Documentation Index
Fetch the complete documentation index at: https://photocli.com/llms.txt
Use this file to discover all available pages before exploring further.
photo-cli copy reads photos from an input folder, renames and reorganizes them into a new output folder using each photo’s EXIF date taken and optional GPS reverse geocode address, then writes a CSV report summarizing every file processed. Your source folder is never touched.
Synopsis
Key behavior
- Reads all photos from the input folder (or the current directory if
--inputis omitted). - Copies each photo to the output folder with a new name and folder structure derived from EXIF metadata.
- Photos with missing dates or coordinates are handled according to the
--no-taken-dateand--no-coordinateflags rather than silently dropped. - Generates
photo-cli-report.csvin the output folder root after every run. - Never modifies, moves, or deletes files in the input folder.
Add
--dry-run (-d) to simulate the entire process without writing any files to disk. A separate photo-cli-dry-run.csv report is produced so you can review what would happen before committing.Required arguments
File system path where the new organized folder will be created. The folder is created automatically if it does not already exist.
File naming strategy applied to every copied photo. Choose one of the following values:
| Name | Value |
|---|---|
| Numeric | 1 |
| Day | 2 |
| DateTimeWithMinutes | 3 |
| DateTimeWithSeconds | 4 |
| Address | 5 |
| DayAddress | 6 |
| DateTimeWithMinutesAddress | 7 |
| DateTimeWithSecondsAddress | 8 |
| AddressDay | 9 |
| AddressDateTimeWithMinutes | 10 |
| AddressDateTimeWithSeconds | 11 |
Controls how photos are read from the input folder and how the output folder hierarchy is structured.
| Name | Value |
|---|---|
| Single | 1 |
| SubFoldersPreserveFolderHierarchy | 2 |
| FlattenAllSubFolders | 3 |
Number formatting used when
--naming-style is Numeric or when disambiguating photos that share the same generated name.| Name | Value |
|---|---|
| AllNamesAreSameLength | 1 |
| PaddingZeroCharacter | 2 |
| OnlySequentialNumbers | 3 |
Action to take when a photo has no EXIF date taken.
| Name | Value |
|---|---|
| Continue | 0 |
| PreventProcess | 1 |
| DontCopyToOutput | 2 |
| InSubFolder | 3 |
| AppendToEndOrderByFileName | 4 |
| InsertToBeginningOrderByFileName | 5 |
Action to take when a photo has no GPS coordinate.
| Name | Value |
|---|---|
| Continue | 0 |
| PreventProcess | 1 |
| DontCopyToOutput | 2 |
| InSubFolder | 3 |
Optional arguments
File system path to read photos from. Defaults to the current working directory. No files in this path are ever modified.
Simulate the copy process without writing any files to the output folder. No extra value required — pass the flag alone.
Groups photos into date- or address-based subfolders. Cannot be used when
--process-type is SubFoldersPreserveFolderHierarchy.| Name | Value |
|---|---|
| YearMonthDay | 1 |
| YearMonth | 2 |
| Year | 3 |
| Address | 4 |
| AddressFlat | 5 |
| AddressHierarchy | 6 |
Appends date range or address information to folder names cloned from the source hierarchy. Must be combined with
--folder-append-location. Only applies when --process-type is SubFoldersPreserveFolderHierarchy.| Name | Value |
|---|---|
| FirstYearMonthDay | 1 |
| FirstYearMonth | 2 |
| FirstYear | 3 |
| DayRange | 4 |
| MatchingMinimumAddress | 5 |
Controls whether the appended string is placed before or after the original folder name. Must be combined with
--folder-append.| Name | Value |
|---|---|
| Prefix | 1 |
| Suffix | 2 |
Action to take when a file cannot be parsed as a valid photo format.
| Name | Value |
|---|---|
| Continue (default) | 0 |
| PreventProcess | 1 |
| DontCopyToOutput | 2 |
| InSubFolder | 3 |
Verifies every copied file by comparing its SHA1 hash against the original. All hashes are also written to
sha1.lst in the output folder so you can re-verify later with sha1sum --check sha1.lst.Maximum expected day difference between the earliest and latest photo taken dates. If the range exceeds this value, the process stops before copying.
Action to take when any photo has missing reverse geocode information.
| Name | Value |
|---|---|
| Continue (default) | 0 |
| PreventProcess | 1 |
Third-party provider used to resolve GPS coordinates into a human-readable address. See reverse geocoding overview for provider setup and API key details.
| Name | Value |
|---|---|
| Disabled | 0 |
| BigDataCloud | 1 |
| OpenStreetMapFoundation | 2 |
| GoogleMaps | 3 |
| LocationIq | 5 |
Space-separated OpenStreetMap address property names used to build the address string. Required when
--reverse-geocode is OpenStreetMapFoundation or LocationIq. Example: country city town suburb. Use photo-cli address to discover available property names for a given photo.Space-separated BigDataCloud admin level numbers used to build the address string. Required when
--reverse-geocode is BigDataCloud.API key for BigDataCloud. You can also set this via the
PHOTO_CLI_BIG_DATA_CLOUD_API_KEY environment variable or the BigDataCloudApiKey setting.Space-separated Google Maps address component types. Required when
--reverse-geocode is GoogleMaps.API key for Google Maps. You can also set this via the
PHOTO_CLI_GOOGLE_MAPS_API_KEY environment variable or the GoogleMapsApiKey setting.API key for LocationIq. You can also set this via the
PHOTO_CLI_LOCATIONIQ_API_KEY environment variable or the LocationIqApiKey setting.Bypass the free-tier rate limit when using LocationIq with a paid license.
Language/culture value to get localized address results from the reverse geocode provider. See your provider’s documentation for supported values.
Example
The following command preserves your existing folder hierarchy, renames each file with its date and address, prefixes each folder with the date range of photos inside it, and routes photos with missing data into dedicated subfolders.Console output
Folder structure before and after
| Original | After photo-cli |
|---|---|
├── DSC_5727.jpg | ├── 2005.08.13_09.47.23-Kenya.jpg |
├── GOPR6742.jpg | ├── 2012.06.22_19.52.31-United Kingdom-Ascot-Sunninghill and Ascot.jpg |
├── Italy album/ | ├── 2005.12.14-2008.10.22-Italy album/ |
│ ├── DJI_01732.jpg | │ ├── 2008.10.22_16.29.49-Italia-Arezzo.jpg |
│ └── IMG_2371.jpg | ├── Italy album/no-address/IMG_2371.jpg |
└── Spain Journey/ | ├── 2015.04.10-2015.04.10-Spain Journey/ |
└── IMG_5397.jpg | └── Spain Journey/no-address-and-no-photo-taken-date/IMG_5397.jpg |
CSV report
After every run,photo-cli-report.csv is created in the output folder root. It contains one row per photo with the following columns:
| Column | Description |
|---|---|
PhotoPath | Absolute path to the original source file |
PhotoNewPath | Relative path to the copied file in the output folder |
PhotoDateTaken | EXIF date and time the photo was taken |
ReverseGeocodeFormatted | Human-readable address built from the configured provider and properties |
Latitude | GPS latitude extracted from EXIF |
Longitude | GPS longitude extracted from EXIF |
PhotoTakenYear | Year component of the taken date |
PhotoTakenMonth | Month component of the taken date |
PhotoTakenDay | Day component of the taken date |
PhotoTakenHour | Hour component of the taken date |
PhotoTakenMinute | Minute component of the taken date |
PhotoTakenSeconds | Seconds component of the taken date |
Address1–Address8 | Individual address components returned by the reverse geocode provider |