Bagaimana Anda bisa memindahkan (atau menyalin) semua file ke direktori dengan awalan nama file yang sama?

9

Menggunakan Bash

Jadi katakanlah saya memiliki banyak file yang ditempatkan secara acak di direktori induk ~/src, saya ingin mengambil semua file yang cocok dengan sufiks tertentu dan memindahkan (atau menyalin) ke ~/distdirektori.

Mari kita asumsikan untuk tujuan ini bahwa semua nama file memiliki konvensi penamaan ini:

<filename_prefix>.<filename_suffix>

Saya menemukan bahwa ini adalah cara cepat untuk mendapatkan semua file dengan tertentu filename_suffixdan meletakkannya di folder dist:

mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;

Sekarang selangkah lebih maju ... bagaimana saya bisa menggunakan output dari find, dalam hal ini filename, dan menggunakan filename_prefixuntuk menghasilkan direktori dengan nama yang sama ~/distdan kemudian memindahkan (atau menyalin) semua file dengan awalan itu ke direktori yang sesuai?

mkdir ~/dst
find source -name "*.xrt,*.ini,*.moo" -exec mv -i {} -t ~/dst \;

Intinya, bagaimana cara mengubah perintah di atas (atau mungkin menggunakan perintah lain), untuk membuat struktur seperti ini

(KELUARAN)

~/dist/people/people.xrt
~/dist/games/games.xrt
~/dist/games/games.moo
~/dist/games/games.ini
~/dist/monkeys/monkeys.ini
~/dist/monkeys/monkeys.xrt

dari pohon direktori seperti ini?

(MEMASUKKAN)

~/src/xrt/people.xrt
~/src/xrt/games.xrt
~/src/conf/games.ini
~/src/pack/monkeys.xrt
~/src/e344/games.moo
~/src/e344/monkeys.moo
~/src/en-us/monkeys.ini
qodeninja
sumber

Jawaban:

10

Akan sangat sulit untuk mengatakan findapa yang harus dilakukan dalam kasus ini.

Lebih baik gunakan shell:

for i in **/*.{xrt,ini,moo}; do
  FILE=$(basename "$i")
  DIR=~/dst/${FILE%.*}
  echo mkdir -p -- "$DIR"
  echo mv -i -t "$DIR" -- "$i"
done

Gunakan shopt -s globstaruntuk membuat **glob bekerja (atau gunakan zsh!). Dan hapus echos nanti jika perintah mencetak apa yang Anda inginkan.

Stéphane Gimenez
sumber
menggunakan bash apakah ini sama?
qodeninja
@codeninja shopt -s globstar, lihat edit saya. Jika hanya ada dua level, Anda dapat menggunakan */*.*dan snipet akan bekerja di shell apa pun.
Gilles 'SO- stop being evil'
2

baris perintah find curang:

find source -name "*.xrt,*.ini,*.moo" -exec env file={} bash -c 'base="$(basename "$file")";dir="dst/${base%.*}";mkdir -p "$dir";cp "$file" "$dir"' \;

sebenarnya bekerja di sekitar untuk memanggil skrip bash di find LOL.

= P

yuyichao
sumber
1
Coba tebak apa yang terjadi jika ada file yang disebut ... happy rm -rf /! Jenis kode ini layak mendapat -1.
Stéphane Gimenez
Suntingan Anda tidak cukup: katakanlah Anda mengeklik tautan dan mengunduh Yay" rm -rf / "Rox0r.avi, sekali lagi ada masalah ...
Stéphane Gimenez
(Dan tidak ada cara untuk membuat substitusi semacam ini aman).
Stéphane Gimenez
1
Ah mungkin itu mungkin dilakukan secara berbeda. Tampaknya berikut bekerja: -exec bash -c 'command which uses "$1"' bash '{}' ';'. Yah, toh itu tidak ada gunanya.
Stéphane Gimenez
1
@ StéphaneGimenez selesai, bash bukan satu-satunya hal yang digunakan. LOL
yuyichao