JFrog CLI provides flexibility in how you download, upload, copy, or move files through the use of wildcard or regular expressions with placeholders.

Any wildcard expression enclosed in parentheses in the source path can be matched with a corresponding placeholder (e.g., {1}) in the target path. This allows you to dynamically determine the destination path and filename for an artifact.

How Placeholders Work

ComponentDescription
(*)Capture group in source pattern - matches any characters
{1}First placeholder - references first capture group
{2}Second placeholder - references second capture group
{n}Nth placeholder - references nth capture group

Using Placeholder Examples

Example 1: Upload Files into Dynamically Named Directories

This example uploads each .tgz file from the source into a new directory in the target repository that matches the file's base name. For example, the file froggy.tgz is uploaded to my-local-repo/froggy/, which creates the froggy folder in Artifactory.

jf rt u "(*).tgz" my-local-repo/{1}/ --recursive=false

Breakdown:

Pattern PartDescription
(*).tgzCaptures the filename (without extension) into group 1
{1}/Uses the captured filename as the directory name
--recursive=falseOnly processes files in the current directory (default is true)

Result:

Source FileTarget Path
froggy.tgzmy-local-repo/froggy/froggy.tgz
ribbit.tgzmy-local-repo/ribbit/ribbit.tgz

Example 2: Upload Files with Modified Names

This example uploads all files with names that begin with frog to the frogfiles folder, appending the suffix -up to each filename. For example, a file named froggy.tgz is renamed to froggy.tgz-up.

jf rt u "(frog*)" my-local-repo/frogfiles/{1}-up --recursive=false

Breakdown:

Pattern PartDescription
(frog*)Captures filenames starting with "frog" into group 1
{1}-upAppends "-up" suffix to the captured filename
--recursive=falseOnly processes files in the current directory

Result:

Source FileTarget Path
froggy.tgzmy-local-repo/frogfiles/froggy.tgz-up
frog-lib.jarmy-local-repo/frogfiles/frog-lib.jar-up

Example 3: Organize Uploaded Files by Extension

This example uploads all files from the current directory into the my-local-repo repository, placing them into subdirectories named after their file extensions.

jf rt u "(*).(*)" my-local-repo/{2}/{1}.{2} --recursive=false

Breakdown:

Pattern PartDescription
(*).(*)Captures filename (group 1) and extension (group 2)
{2}/Uses extension as directory name
{1}.{2}Reconstructs original filename
--recursive=falseOnly processes files in the current directory

Result:

Source FileTarget Path
froggy.tgzmy-local-repo/tgz/froggy.tgz
ribbit.zipmy-local-repo/zip/ribbit.zip
pond.jarmy-local-repo/jar/pond.jar

Example 4: Copy Files and Append a Suffix

This example copies all .zip files from the rabbit/ directory in the source-frog-repo to the same path in the target-frog-repo and appends .cp to each copied filename.

jf rt cp "source-frog-repo/rabbit/(*.zip)" target-frog-repo/rabbit/{1}.cp

Breakdown:

Pattern PartDescription
source-frog-repo/rabbit/(*.zip)Captures .zip filenames from source path
target-frog-repo/rabbit/{1}.cpPlaces files in target with .cp suffix

Result:

Source PathTarget Path
source-frog-repo/rabbit/archive.ziptarget-frog-repo/rabbit/archive.zip.cp
source-frog-repo/rabbit/data.ziptarget-frog-repo/rabbit/data.zip.cp

Command Reference

Supported Commands

Placeholders are supported in the following commands:

CommandAbbreviationDescription
jf rt uploadjf rt uUpload files to Artifactory
jf rt downloadjf rt dlDownload files from Artifactory
jf rt copyjf rt cpCopy files within Artifactory
jf rt movejf rt mvMove files within Artifactory

Relevant Flags

FlagDefaultDescription
--recursivetrueWhen true, collects files from sub-folders. Set to false to process only the current directory.
--flatfalseWhen true, ignores source directory structure. When false, preserves hierarchy.
--regexpfalseWhen true, interprets the pattern as a regular expression instead of wildcards.

Advanced Usage

Using Regular Expressions with Placeholders

When using --regexp, you can use regex capture groups instead of wildcard patterns:

jf rt u "(.+)-sources\.jar" libs-release-local/{1}/ --regexp

This captures the artifact name before -sources.jar and uses it as a directory.

Multiple Capture Groups

You can use multiple capture groups and reference them in any order:

jf rt u "(org)/(module)/(*).jar" my-repo/{2}/{1}/{3}.jar

File Spec Usage

Placeholders also work in File Specs:

{
  "files": [
    {
      "pattern": "(*).tgz",
      "target": "my-local-repo/{1}/",
      "recursive": "false"
    }
  ]
}