tar展開時に不要な親ディレクトリを取り除きたい
GitHubのリリースアーカイブなど、tarアーカイブはmyproject-1.2.3/のような親ディレクトリを1つ持つ構成であることが多い。そのまま展開すると余分な階層ができてしまい、展開先のディレクトリ構成をそろえたい場合に扱いづらい。--strip-componentsオプションを使うと、展開時に先頭のパスから指定した階層数を取り除ける。
–strip-components オプションの基本
--strip-components=Nを指定すると、アーカイブ内の各ファイルのパスから先頭N階層を除去して展開する。
$ tar -xzf archive.tar.gz --strip-components=N
具体例
以下のような構造のmyproject-1.2.3.tar.gzがあるとする。
myproject-1.2.3/
├── src/
│ └── main.go
├── config/
│ └── app.yaml
└── README.md
展開する前に-tvfオプションでアーカイブの中身を確認すると、親ディレクトリの階層数が分かる。
$ tar -tvf myproject-1.2.3.tar.gz
drwxr-xr-x root/root 0 2026-07-10 21:26 myproject-1.2.3/
-rw-r--r-- root/root 7 2026-07-10 21:26 myproject-1.2.3/README.md
drwxr-xr-x root/root 0 2026-07-10 21:26 myproject-1.2.3/src/
-rw-r--r-- root/root 5 2026-07-10 21:26 myproject-1.2.3/src/main.go
drwxr-xr-x root/root 0 2026-07-10 21:26 myproject-1.2.3/config/
-rw-r--r-- root/root 7 2026-07-10 21:26 myproject-1.2.3/config/app.yaml
すべてのパスがmyproject-1.2.3/から始まっており、親ディレクトリは1階層であることが分かる。
-tに--strip-componentsを付けても一覧表示のパスは変化しない。--strip-componentsは展開(-x)時のパス変換にのみ効き、一覧表示には反映されない仕様のため、-tで階層を取り除いた結果を事前にプレビューできない。
$ tar -tvf myproject-1.2.3.tar.gz --strip-components=1
drwxr-xr-x root/root 0 2026-07-10 21:26 myproject-1.2.3/
-rw-r--r-- root/root 7 2026-07-10 21:26 myproject-1.2.3/README.md
drwxr-xr-x root/root 0 2026-07-10 21:26 myproject-1.2.3/src/
-rw-r--r-- root/root 5 2026-07-10 21:26 myproject-1.2.3/src/main.go
drwxr-xr-x root/root 0 2026-07-10 21:26 myproject-1.2.3/config/
-rw-r--r-- root/root 7 2026-07-10 21:26 myproject-1.2.3/config/app.yaml
--strip-components=1を付けていない-tvfの結果と完全に同じ出力になる。この1階層を取り除いて展開するには--strip-components=1を指定する。
$ tar -xzf myproject-1.2.3.tar.gz -C extract --strip-components=1
extractディレクトリにはmyproject-1.2.3/を除いたREADME.md、src/main.go、config/app.yamlが直接展開される。-Cオプションで展開先ディレクトリを指定しておくと、myproject-1.2.3という名前のディレクトリを事前に作る必要がない。
階層数がファイルのパス階層以上の場合の挙動
--strip-componentsに指定した数が、そのファイルのパスの階層数以上になる場合、そのファイルは展開されずスキップされる。
先ほどのmyproject-1.2.3.tar.gzに--strip-components=2を指定して展開すると、一部のファイルがスキップされる。-vオプションを付けて展開すると、実際に処理されたファイルを確認できる。
$ tar -xzvf myproject-1.2.3.tar.gz -C extract2 --strip-components=2
myproject-1.2.3/src/main.go
myproject-1.2.3/config/app.yaml
出力にmyproject-1.2.3/README.mdが含まれていない。README.mdはmyproject-1.2.3/README.mdという2階層のパスしか持たず、2階層すべてを取り除くとファイル名すら残らないため、展開されずスキップされる。src/main.goとconfig/app.yamlは3階層のパスを持つため、2階層取り除いてもmain.goやapp.yamlとして展開される。
-vで表示されるのはアーカイブ内の元のパスであり、実際に展開されるパスとは異なる点に注意する。アーカイブ内のファイルによって階層数は異なるため、意図しないファイルまでスキップされる場合がある。
GitHubのリリースアーカイブを展開する例
GitHubのリリースアーカイブはリポジトリ名-バージョン/という親ディレクトリを持つことが多く、--strip-components=1との組み合わせがよく使われる。
$ mkdir -p /usr/local/mytool
$ curl -L https://github.com/example/mytool/archive/refs/tags/v1.2.3.tar.gz \
| tar -xz -C /usr/local/mytool --strip-components=1
パイプでtarに渡す場合も-Cと--strip-componentsを組み合わせることで、余分な親ディレクトリを作らずに任意の場所へ展開できる。
関連記事
- 【tar】-Cオプションで作業ディレクトリを指定して展開・作成する
- 【tar】--excludeオプションでアーカイブ・展開時にファイルを除外する
- tarとunzipで特定のファイルだけを抽出する
- さくらのVPSのRocky Linux 8でtarが無いときの対処法
