English
Renaming directories during packaging with the tar command on macOS and Linux

Background
In daily development and operations work, we often need to package directories for distribution. Sometimes, we want the packaged directory name to be different from the source directory name, but we do not want to modify the original directory structure.
For example, consider this scenario:
Source directory:
x86_64Expected directory name after packaging:
finalfile-csi-7.2.2-mulRequirement:Do not modify the original directory., directly pass
tarRename the command during packaging.
Implementation methods for different systems
Because macOS and Linux use different tar implementations, their rename options also differ:
Linux Using GNU tar, supports
--transformOptionsmacOS Use BSD tar (bsdtar), supports
-sOption
Linux (GNU tar)
bash
tar -zcvf finalfile-csi-7.2.2-mul.tar.gz --transform='s/x86_64/finalfile-csi-7.2.2-mul/' ./x86_64macOS (BSD tar / bsdtar)
bash
tar -zcvf finalfile-csi-7.2.2-mul.tar.gz -s '/x86_64/finalfile-csi-7.2.2-mul/' ./x86_64Execution effect (applicable to both)
bash
a ./finalfile-csi-7.2.2-mul
a ./finalfile-csi-7.2.2-mul/finalfilefs-storage-class.yaml
a ./finalfile-csi-7.2.2-mul/helm-v3.9.0_x86.tar.gz
a ./finalfile-csi-7.2.2-mul/images.tar
a ./finalfile-csi-7.2.2-mul/finalfile_helm_chart_x86.tar.gzFrom the output, it can be seen that the source directory ./x86_64 was successfully renamed to during packaging ./finalfile-csi-7.2.2-mul, and the original directory x86_64 has not been modified.
Parameter details
GNU tar(Linux)
| Parameter | Explanation |
|---|---|
--transform='s/old/new/' | Rename paths using sed-style replacement expressions |
-z | Compress using gzip |
-c | Create an archive file |
-v | Show detailed process |
-f | Specify archive file name |
Note:--transform Option must Put it in the source file/directory.Before.
BSD tar(macOS)
| Parameter | Description |
|---|---|
-s '/old/new/' | Replace the path name during packaging. |
-z | Compress using gzip |
-c | Create archive file |
-v | Show detailed process |
-f | Specify archive file name |
Attention:-s The options are likewise.must Place in the source file/directory Before.
Verify the packaging result
View archive contents
bash
tar -tzf finalfile-csi-7.2.2-mul.tar.gzOutput example:
./finalfile-csi-7.2.2-mul/
./finalfile-csi-7.2.2-mul/finalfilefs-storage-class.yaml
./finalfile-csi-7.2.2-mul/helm-v3.9.0_x86.tar.gz
./finalfile-csi-7.2.2-mul/images.tar
./finalfile-csi-7.2.2-mul/finalfile_helm_chart_x86.tar.gzDecompression test
bash
# Create test directory
mkdir test_extract && cd test_extract
# Decompress
tar -xzf ../finalfile-csi-7.2.2-mul.tar.gz
# View results
ls -la
# You should see the finalfile-csi-7.2.2-mul directory.
# The original x86_64 directory still exists and has not been modified.Cross-platform compatibility solution
If you need to write a script that can run on both macOS and Linux, you can detect the tar version and choose the appropriate options:
bash
#!/bin/bash
SRC_DIR="./x86_64"
NEW_NAME="finalfile-csi-7.2.2-mul"
ARCHIVE_NAME="finalfile-csi-7.2.2-mul.tar.gz"
# Detect tar type
if tar --version 2>&1 | grep -q "GNU"; then
# GNU tar (Linux)
tar -zcvf "$ARCHIVE_NAME" --transform="s/x86_64/$NEW_NAME/" "$SRC_DIR"
elif tar --version 2>&1 | grep -q "bsdtar"; then
# BSD tar (macOS)
tar -zcvf "$ARCHIVE_NAME" -s "/x86_64/$NEW_NAME/" "$SRC_DIR"
else
echo "unknown tar implementation"
exit 1
fiAdvanced usage
1. Use different separators (when the path contains / time)
bash
# GNU tar uses | as a delimiter
tar -zcvf output.tar.gz --transform='s|x86_64|finalfile-csi-7.2.2-mul|' ./x86_64
# BSD tar uses | as a separator
tar -zcvf output.tar.gz -s '|x86_64|finalfile-csi-7.2.2-mul|' ./x86_642. Exact match of the full path
bash
# GNU tar: match only complete directory names
tar -zcvf output.tar.gz --transform='s/^x86_64$/finalfile-csi-7.2.2-mul/' x86_64
# BSD tar: only match complete directory names
tar -zcvf output.tar.gz -s '/^x86_64$/finalfile-csi-7.2.2-mul/' x86_643. Multiple renaming rules
bash
# GNU tar: multiple replacements
tar -zcvf output.tar.gz \
--transform='s/x86_64/new-name1/' \
--transform='s/old-dir/new-name2/' \
./source
# BSD tar: multiple replacements
tar -zcvf output.tar.gz \
-s '/x86_64/new-name1/' \
-s '/old-dir/new-name2/' \
./source4. Rename only the directory, without modifying internal file paths
If you only want to rename the top-level directory without modifying the paths of internal files, you can use --transform With regex:
bash
# GNU tar: replace only the top-level directory name (s#^\./x86_64#./new-name#)
tar -zcvf output.tar.gz --transform='s#^\./x86_64#./new-name#' ./x86_64
# BSD tar: Use flags to control replacement scope
tar -zcvf output.tar.gz -s '/^\.\/x86_64/\.\/new-name/' ./x86_64Common Errors and Solutions
Error 1: Option position error
bash
# Error: The rename option is placed after the source file
tar -zcvf output.tar.gz ./x86_64 --transform='s/x86_64/new/'
# Correct: rename options must come before the source file
tar -zcvf output.tar.gz --transform='s/x86_64/new/' ./x86_64Error 2: Path mismatch
bash
# Error: Path mismatch, replacement failed
tar -zcvf output.tar.gz --transform='s/x86_64/new/' x86_64
# Correct: Ensure the path matches.
tar -zcvf output.tar.gz --transform='s/^x86_64$/new/' x86_64
# or
tar -zcvf output.tar.gz --transform='s/\.\/x86_64/\.\/new/' ./x86_64Error 3: Using --transform on macOS
bash
# Error: BSD tar does not support --transform
tar -zcvf output.tar.gz --transform='s/x86_64/new/' ./x86_64
# Correct: use -s
tar -zcvf output.tar.gz -s '/x86_64/new/' ./x86_64Summary
| system | tar implementation | Rename option | Example command |
|---|---|---|---|
| Linux | GNU tar | --transform | tar -czf out.tar.gz --transform='s/old/new/' ./old |
| macOS | BSD tar | -s | tar -czf out.tar.gz -s '/old/new/' ./old |
Key points:
Rename options (
--transformor-s) must be placed in the source file/directory beforeThe original directory will not be modified; only the paths inside the tar package are affected.
GNU tar usage
--transform='s/old/new/'BSD tar usage
-s '/old/new/'Both support using
|as a delimiter
Pass directly tar The command itself implements renaming, no need to mv Operation, keep the original directory intact!