Cara mengatur file di direktori yang sesuai bernama dari baris perintah di Linux

1

Saya memiliki direktori yang diisi dengan berbagai file, yang dinamai berbeda (yaitu tidak dinamai dengan pola tertentu) dan dengan ekstensi yang berbeda, dan saya ingin meletakkan setiap file dalam subdirektori yang baru dibuat dinamai setiap file; apa cara terbaik untuk mencapainya dari baris perintah di Linux?
Ini kedengarannya agak membingungkan, izinkan saya membuat dan contoh: mari kita memanggil file acak di direktori ./filename.ext, saya ingin meletakkannya di subdirektori yang disebut ./filenamesehingga secara efektif jalan baru akan ./filename/filename.ext.

Saya melakukan beberapa percobaan dengan langkah-langkah berikut:

  • Saya telah membuat beberapa file uji, dari file-1.txthingga file-9.txt, di dalam direktori pengujian denganfor num in {1..9}; do touch file-$num.txt; done
  • Saya telah membuat direktori bernama setelah setiap nama file dengan for name in $(eval ls | cut -b 1-6); do mkdir $name; done
  • Saya telah memindahkan file sumber di direktori masing-masing for name in $(eval ls | grep -e ".txt" | cut -b 1-6); do mv $name.txt $name/$name.txt; done

Seperti yang Anda lihat, solusi ini berfungsi, tetapi kelemahannya adalah ia berfungsi hanya dalam kasus ini, dengan file dengan nama file yang panjang dan dengan ekstensi tertentu. Jika saya memiliki beberapa file dengan nama dan ekstensi yang berbeda, ini tidak akan berguna sama sekali. Penggunaan cutperintah bukanlah solusi yang ideal di sini, saya kira, tetapi saya belum menemukan sesuatu yang lebih baik saat ini.

Sebagai bonus, akan lebih baik untuk menemukan cara untuk membuat subdir secara otomatis ketika memindahkan / mengganti nama file, tanpa harus menggunakan mkdirsebelumnya (jadi ketika saya lsbenar-benar mengganti nama, saya tidak perlu khawatir mengecualikan direktori yang baru dibuat. ); tetapi pada akhirnya ini adalah masalah sekunder.

Sekhemty
sumber

Jawaban:

2

Saya kira solusi untuk masalah Anda disebut substitusi parameter (lihat deskripsi terperinci ). Diberikan nama file di filenameAnda akan mendapatkan ekstensi menggunakan ${filename##*.}dan nama tanpa ekstensi dengan ${filename%.*}.

Yang mengatakan, Anda mungkin ingin memodifikasi forlingkaran Anda seperti:

# for all (*) files in the current directory
for i in *;
do
    # -f checks if it is a file (skip directories)
    [ -f "$i" ] || continue
    # store the file name in filename
    filename=$(basename $i)
    # ext = the extension of the file (here we don't care, jfi)
    ext="${filename##*.}"
    # dir = the file name without its extension
    dir="${filename%.*}"
    # create the directory
    mkdir -p $dir
    # move the file in that directory
    mv $i $dir
done

Sayangnya, saya tidak mendapatkan poin dari tugas bonus Anda , jadi itu akan tetap menjadi tantangan terbuka ... :)

binfalse
sumber
Ini bekerja dengan sempurna, maukah Anda menjelaskan kepada saya apa yang telah saya lakukan :)?
Sekhemty
Saya baru saja menambahkan beberapa komentar ke kode saya. Tapi seperti yang saya katakan triknya disebut substitusi parameter dan saya sarankan untuk mengunjungi tautan yang saya berikan untuk memahami apa yang terjadi :)
binfalse
1

Berikut ini adalah pendekatan dengan skrip shell lebih sedikit, tetapi lebih banyak perintah.

   find -maxdepth 1 -type f > file-list

Temukan semua file di direktori saat ini dan simpan daftar ini.

   grep -o '\./.*\.' file-list | sed s/\.$// > dir-list

Saring daftar ini untuk hanya menyertakan nama file yang memiliki titik di suatu tempat. Hapus titik terakhir ini dengan sed, simpan daftar ini.

   mkdir $(<dir-list)

Buat semua folder.

   sort dir-list > dir-list.s
   sort file-list > file-list.s

Ini untuk mengatur (berdasarkan pesanan) nama file dengan nama folder>

   paste file-list dir-list

Ini akan terlihat salah karena daftar file file akan ada di sini. Dalam kasus saya ada juga file yang disebut acak . Hapus nama-nama itu dari daftar file.

   sed -E '/^\.\/(random|file-list)$/d' -i file-list
   sort file-list > file-list.s

Selidiki output dari perintah berikut ini sekali lagi: tempel daftar file-daftar-dir

Seharusnya terlihat seperti ini:

   ./CCrtWW].GdH   ./CCrtWW]
   ./c[ifzJlKnEYXO.wXF ./c[ifzJlKnEYXO
   ./FAEhz.u[A ./FAEhz
   ./FGMlrKcJHF.pHp    ./FGMlrKcJHF
   ./HGxKPWZK.MpK  ./HGxKPWZK
   ./JxwNrN.zoj    ./JxwNrN

Setelah terlihat benar, buat skrip shell dari daftar dan berikan matahari:

 paste file-list dir-list | sed 's/^/mv -v /' | sh
Ярослав Рахматуллин
sumber
Ini mengasumsikan tidak ada spasi atau karakter aneh lainnya dalam nama file.
Ярослав Рахматуллин