Cara memilih nama direktori selama pembatalan

125

Katakanlah saya memiliki nama file ugly_name.tar, yang ketika diekstraksi, menjadi ugly_namedirektori. Perintah apa yang bisa saya gunakan sehingga nama direktori yang dihasilkan adalah pretty_namesebaliknya?

tepang
sumber

Jawaban:

172

Ini seharusnya bekerja:

mkdir pretty_name && tar xf ugly_name.tar -C pretty_name --strip-components 1

-Cperubahan ke direktori yang ditentukan sebelum membongkar (atau mengemas). --strip-componentsmenghapus jumlah direktori yang ditentukan dari nama file yang disimpan dalam arsip.

Perhatikan bahwa ini tidak benar-benar portabel. GNU tar dan setidaknya beberapa tars BSD memiliki --strip-componentsopsi, tetapi tampaknya tidak ada pada platform mirip-unix lainnya.

Cara bodoh melakukan ini akan bekerja cukup banyak di mana-mana.

tar xf ugly_name.tar && mv ugly_name pretty_name
Tikar
sumber
Saya pikir saya akan tetap dengan versi bodoh :)
phunehehe
28
@ phunehehe: salah satu keuntungan dari versi pintar ini adalah Anda tidak perlu tahu sebelumnya apa nama direktori yang tidak
diarsipkan
2
Bolehkah saya menambahkan, bahwa ini berfungsi lebih dari "Pretty_name". Anda juga dapat membatalkan pengarsipan ke direktori tertentu dengan cara ini. Contoh:tar -xvf /tmp/backupfiles.tar -C /var/www/
Jenderal Redneck
2
Saya biasanya menggunakan cara bodoh, dan saya menggunakan wildcard kalau-kalau saya tidak tahu apa nama jeleknya atau saya tidak ingin menuliskannya. mv ugly-* pretty_name
David Grayson
1
Cara bodoh tidak berfungsi jika sudah ada ugly_namedirektori. Ngomong-ngomong, kecantikan ada di mata yang melihatnya.
kmiklas
30

Dengan tar GNU ≥1.16, gunakan --transformuntuk menerapkan transformasi sed regexp ke setiap nama file (transformasi diterapkan pada path lengkap dalam arsip):

tar xf foo.tar --transform 's!^ugly_name\($\|/\)!pretty_name\1!'

Jika ugly_namekomponen tingkat atas dari semua nama file dalam arsip, Anda tidak perlu repot dengan pencocokan tepat:

tar xf foo.tar --transform 's/ugly_name/pretty_name/'

Jika Anda tidak tahu nama direktori tingkat atas, Anda masih dapat menggunakan metode ini, meskipun Anda mungkin lebih suka --strip-components.

tar xf foo.tar --transform 's!^[^/]\+\($\|/\)!pretty_name\1!'

Dengan pax, utilitas arsip POSIX, gunakan -sopsi, yang menggunakan ekspresi pengganti seperti sed sebagai argumen.

pax -rf foo.tar -s '!^ugly_name\($\|/\)!pretty_name\1!'
pax -rf foo.tar -s '/ugly_name/pretty_name/'
pax -rf foo.tar -s '!^[^/]\+\($\|/\)!pretty_name\1!'
Gilles
sumber
9

Gunakan ini :

tar -xvf ugly_name.tar
mv ugly_name pretty_name
Rupesh Mande
sumber
9
Anda mungkin lebih suka menggunakan &&operator daftar di antara dua perintah itu, jadi yang kedua hanya dijalankan jika yang pertama berhasil.
manatwork
1
Ini bisa memiliki konsekuensi yang tidak diinginkan jika direktori ugly_namesudah ada.
Drew Dormann
7

Cara paling sederhana

tar xvf dml/ugly_name.tar --one-top-level=pretty_name --strip-components 1
marquicus
sumber
(1) Ini jelas bukan cara paling sederhana, karena smac89 memposting jawaban yang menampilkan --one-top-level=pretty_nametanpa --strip-components 1. (2) Sebaliknya, jawaban yang diterima (diposting oleh Mat) fitur --strip-components 1tanpa --one-top-level=pretty_name. (3) Dapatkah Anda menjelaskan mengapa jawaban Anda, menggabungkan pilihan-pilihan ini, lebih baik daripada yang sebelumnya? Tolong jangan menanggapi dalam komentar; edit  jawaban Anda untuk membuatnya lebih jelas dan lebih lengkap.
G-Man
mungkin contoh nyata dapat membantu Anda mengklarifikasi: `wget dev.mysql.com/get/Downloads/MySQL-5.7/… tar xvf mysql-5.7.23-linux-glibc2.12-x86_64.tar.gz --satu-atas -level = mysql57 --strip-components 1 `
marquicus
Jawaban ini lebih anggun dari pada yang paling banyak mendapat dukungan .
KaiserKatze
@ G-Man --strip-component 1diperlukan, dengan metode mkdiratau --strip-components 1, jika tidak, Anda hanya mendapatkannya pretty_name/ugly_name/.
davidA
Ini memang cara paling sederhana
smac89
2

Dari askUbuntu, jawaban ini berhasil untuk saya:

tar zxvf ugly_name.tgz --one-top-level=pretty_name

`--satu tingkat atas [= dir] '

Memberitahu tar untuk membuat direktori baru di bawah direktori ekstraksi (atau yang diteruskan ke `-C ') dan menggunakannya untuk menjaga terhadap tarbombs. Dengan tidak adanya argumen dir, nama direktori baru akan sama dengan nama dasar arsip (nama file dikurangi akhiran arsip, jika dikenali). Setiap nama anggota yang tidak dimulai dengan nama direktori itu (setelah transformasi dari `--transformasi 'dan` --strip-komponen') akan diawali dengan itu. Sufiks nama file yang dikenali adalah `.tar ', dan sufiks kompresi apa pun yang dikenali oleh See -auto-kompres .


Memperbarui

Seperti yang ditunjukkan dalam komentar , metode ini tidak berfungsi untuk arsip yang dibentuk dengan benar, namun seperti yang ditunjukkan oleh jawaban lain , Anda harus menambahkan --strip-components 1ini agar benar-benar berfungsi. Saya telah menguji dengan opsi baru ini dan itu berfungsi baik untuk arsip dengan nama tingkat atas dan yang tidak.

smac89
sumber
Masalah dengan ini adalah bahwa itu tidak mengubah nama direktori tingkat atas, melainkan menciptakan tingkat baru, bernama pretty_name, dengan direktori tingkat atas asli di dalamnya. Misalnya jika tar xzf ugly_name.tgzakan membuat direktori bernama ugly_name/, maka perintah yang Anda berikan akan dibuat pretty_name/ugly_name/.
davidA
1
@davidA Poin bagus. Saya telah memperbarui jawaban saya untuk menyertakan perbaikan untuk ini
smac89