cara mengganti nama file saat menyalin?

12

Bagaimana saya menyalin (gaya arsip di mana tanggal tidak berubah) semua file dalam direktori cadangan ke direktori pengguna saat mengganti nama setiap file untuk menghapus bagian string acak dari nama (yaitu, -2b0fd460_1426b77b1ee_-7b8e)?

cp dari:

/backup/path/data/Erp.2014.02.16_16.57.03-2b0fd460_1426b77b1ee_-7b8e.etf

untuk:

/home/user/data/Erp.2014.02.16_16.57.03.etf

Setiap file akan selalu dimulai dengan "Erp." diikuti oleh string cap tanggal-waktu diikuti oleh string acak dan kemudian ekstensi ".etf". Saya ingin menyimpan semua elemen nama termasuk cap tanggal-waktu. Saya hanya ingin menghapus string acak.

String acak memungkinkan beberapa cadangan dari file yang sama. Namun, dalam hal ini, saya hanya menjalankan fdupes dan tidak ada duplikat. Jadi saya bisa mengembalikan semua file, menghapus string acak.

Saya mencari perintah bash satu baris untuk melakukannya.

Jika itu tidak berhasil, saya bisa melakukannya dalam dua langkah atau lebih. Saya biasanya menggunakan KRename, tetapi dalam hal ini saya harus melakukannya di bash. (Saya bekerja dari jarak jauh.)

MountainX
sumber

Jawaban:

7

paxdapat melakukan ini sekaligus. Anda bisa melakukannya:

cd /backup/path/data && pax -wrs'/-.*$/.etf/' Erp*etf /home/user/data

paxmempertahankan waktu secara default, tetapi dapat menambah -peuntuk mempertahankan segala sesuatu (paling baik dilakukan sebagai root) atau -ppuntuk mempertahankan izin, misalnya:

cd /backup/path/data && pax -wrs'/-.*$/.etf/' -pe Erp*etf /home/user/data

Kalau tidak ( paxbiasanya tidak tersedia secara default), pasti lebih baik melakukan salinan daripada rename:

cp -a /backup/path/data/Erp*.etf /home/user/data
rename 's/-.*$/.etf/' /home/user/data/Erp*.etf

Dengan cara ini tidak ada proses berbeda dimulai untuk setiap file.

Graeme
sumber
1
Saya bisa melihat bahwa saya harus terbiasa pax. Ini terlihat seperti alat yang sangat berguna. Membuat saya bertanya-tanya mengapa ini bukan standar di lebih banyak distro ...
MountainX
@MountainX, Pertanyaan yang bagus, menurut Wikipedia, paxtelah ada di Linux Standard Base sejak 2005. Ditambah alternatifnya, GNU cpio, mungkin merupakan alat GNU yang paling tidak memiliki fitur.
Graeme
1
+1 untuk solusi terakhir Anda dan Dengan cara ini tidak ada proses berbeda dimulai untuk setiap file. Tetapi rename berbeda pada Fedora / Red Hat: Saya tidak tahu bagaimana menggunakannya dalam kasus ini.
erik
15

Anda dapat menggunakan cpperintah dengan -aopsi

-a, --archive
       same as -dR --preserve=all

Dan kemudian gunakan for for untuk mengganti nama semua file saat menyalinnya:

for file in Erp*etf; do
  cp -a $file destinationDirectory/${file%%-*}.etf
done

Siap. Mulai perintah ini di direktori sumber.

Penjelasan: Ini %%-*akan memotong semua karakter setelah kemunculan pertama tanda hubung / minus -dan .etfpada akhirnya menambahkan lagi ekstensi file.

Nah, dan sebagai satu liner, letakkan semuanya dalam satu baris. :-) Seperti ini

for file in Erp*etf; do cp -a $file destinationDirectory/${file%%-*}.etf; done
erik
sumber
1
Terima kasih, bisakah Anda mengutip dokumentasi untuk %%-*tipnya? Saya penasaran.
soyuka
3

Di zsh, gunakan zmv . Letakkan ini di .zshrc:

autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'

Kemudian gunakan

zcp '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'

Dalam bash:

zsh -c 'autoload zmv; zmv -C $0 $1' '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'

Jika Anda tidak memiliki zsh, cara POSIX menggunakan pax (ini menyalin direktori secara rekursif).

Jika Anda menggunakan sistem terbatas tanpa zsh dan tidak ada pax, Anda dapat menggunakan loop:

for source in /backup/path/data/*-*.etf; do
  basename=${source##*/}
  cp "$source" "/home/user/data/${basename%-*}.${basename##*.}"
done
Gilles 'SANGAT berhenti menjadi jahat'
sumber
1

cptidak memiliki kemampuan itu. Saya ingat cpiobisa melakukan itu, tetapi halaman manual saat ini mengatakan sebaliknya. Namun, (gnu) tarmemang memiliki --transformopsi:

 --transform, --xform EXPRESSION
       use sed replace EXPRESSION to transform file names

Jadi, Anda akan memiliki cmdline seperti:

(cd /backup/path/data; tar --create --transform 's/-.*-....//' .) | (cd /home/user/data; tar --extract)
Ricky Beam
sumber