Maaf jika ada jawaban di tempat lain, saya tidak tahu bagaimana mencari masalah saya.
Saya menjalankan beberapa simulasi pada server HPC linux redhat, dan kode saya untuk menangani struktur folder untuk menyimpan output memiliki bug yang tidak menguntungkan. Kode matlab saya untuk membuat folder adalah:
folder = [sp.saveLocation, 'run_', sp.run_number, '/'];
dimana sp.run_number
bilangan bulat. Saya lupa mengonversinya menjadi string, tetapi karena alasan tertentu menjalankan mkdir(folder);
(di matlab) masih berhasil. Faktanya, simulasi berjalan tanpa hambatan, dan data disimpan ke direktori yang cocok.
Sekarang, ketika struktur folder ditanyai / dicetak saya mendapatkan situasi berikut:
- Ketika saya mencoba untuk tab autocomplete:
run_ run_^A/ run_^B/ run_^C/ run_^D/ run_^E/ run_^F/ run_^G/ run_^H/ run_^I/
- Ketika saya menggunakan
ls
:run_ run_? run_? run_? run_? run_? run_? run_? run_? run_? run_?
. - Ketika saya mentransfer ke mac saya menggunakan rsync
--progress
opsi menunjukkan:run_\#003/
dll dengan (saya berasumsi) nomor yang cocok dengan integer disp.run_number
padded menjadi tiga digit, jadi jalankan 10 adalahrun_\#010/
- Ketika saya melihat folder di finder saya melihat
run_ run_ run_ run_ run_ run_ run_ run_ run_ run_?
- Melihat pertanyaan ini dan menggunakan perintah
ls | LC_ALL=C sed -n l
saya dapatkan:
run_$
run_\001$
run_\002$
run_\003$
run_\004$
run_\005$
run_\006$
run_\a$
run_\b$
run_\t$
run_$
Saya tidak bisa mengelola cd
ke folder menggunakan representasi ini.
Saya memiliki ribuan folder ini, jadi saya harus memperbaikinya dengan skrip. Manakah dari opsi ini yang merupakan representasi folder yang benar? Bagaimana saya bisa merujuk secara terprogram ke folder-folder ini sehingga saya menamainya kembali dengan nama yang diformat dengan benar menggunakan skrip bash? Dan saya rasa demi rasa ingin tahu, bagaimana mungkin ini bisa terjadi?
sumber
^A
tidak secara harfiah^
diikuti olehA
, tetapi Ctrl-A (Anda dapat mengetiknya menggunakan Ctrl-V Ctrl-A karena Ctrl-A umumnya merupakan jalan pintas untuk shell).run_
dan saya harus mengetikkan sesuatu/
. Karakter lain apa pun yang valid, termasuk karakter kontrol. Saya tidak tahu apa yang akan dilakukan matlab jika sp.run_number adalah 0 (mungkin dibatalkan dengan kesalahan atau menghasilkanrun_
, karena byte NUL akan mengakhiri string nama direktori). Tentu saja, ini juga akan bermasalah untuk 16-bit (atau lebih tinggi) nilai-nilai yang memiliki byte NUL di dalamnya, dan juga akan bervariasi sesuai dengan endian-ness dari sistem yang menjalankan matlab.Jawaban:
Anda dapat menggunakan
rename
utilitas perl (aliasprename
ataufile-rename
) untuk mengubah nama direktori.CATATAN: Ini tidak harus bingung dengan
rename
dariutil-linux
, atau versi lain.Ini menggunakan
ord()
fungsi perl untuk mengganti setiap karakter kontrol dalam nama file dengan nomor urut untuk karakter itu. misalnya^A
menjadi 1,^B
menjadi 2, dll.The
-n
pilihan adalah untuk dry-run untuk menunjukkan apa yangrename
akan dilakukan jika Anda membiarkannya. Hapus (atau ganti dengan-v
untuk verbose output) untuk benar-benar mengubah nama.The
e
pengubah dalams/LHS/RHS/eg
operasi menyebabkan perl untuk mengeksekusi RHS (penggantian) sebagai kode perl, dan$1
merupakan data yang cocok (karakter kontrol) dari LHS.Jika Anda ingin angka nol-empuk dalam nama file, Anda dapat menggabungkan
ord()
dengansprintf()
. misalnyaContoh di atas berfungsi jika dan hanya jika
sp.run_number
dalam skrip matlab Anda berada di kisaran 0..26 (sehingga menghasilkan karakter kontrol dalam nama direktori).Untuk menangani SETIAP karakter 1-byte (yaitu mulai dari 0..255), Anda akan menggunakan:
Jika
sp.run_number
bisa> 255, Anda harus menggunakanunpack()
fungsi perl alih-alihord()
. Saya tidak tahu persis bagaimana matlab menghasilkan int yang belum dikonversi dalam sebuah string, jadi Anda harus bereksperimen. Lihatperldoc -f unpack
untuk rincian.misalnya yang berikut ini akan membuka nilai 8-bit dan 16-bit yang tidak ditandatangani dan zero-pad mereka menjadi 5 digit lebar:
sumber
-n
opsi, tetapi ia memberi tahu saya itu opsi yang tidak valid - informasi versi memberi sayarename from util-linux 2.23.2
jadi saya tidak yakin fungsinya samarename
utilitas.util-linux
'srename
sangat berbeda, jauh kurang mampu, dan opsi baris perintah tidak kompatibel. jika Anda menjalankan debian atau sejenisnya, coba instalfile-rename
paketnya. jika tidak instal paket yang sesuai untuk distro Anda. mungkin sudah diinstal, coba jalankanprename
ataufile-rename
bukan hanyarename
.Jadi, akan muncul bahwa
mkdir([...])
di Matlab menyatukan anggota array untuk membangun nama file sebagai string. Tetapi Anda memberikan nomor sebagai gantinya, dan angka adalah apa karakter sebenarnya di komputer. Jadi, kapansp.run_number
itu1
, itu memberi Anda karakter dengan nilai1
, dan kemudian karakter dengan nilai2
, dll.Mereka adalah karakter kontrol, mereka tidak memiliki simbol yang dapat dicetak, dan mencetaknya pada terminal akan memiliki konsekuensi lain. Jadi alih-alih, mereka sering diwakili oleh berbagai jenis pelarian:
\001
(oktal),\x01
(hex),^A
semua representasi umum untuk karakter dengan nilai1
. Karakter dengan nilai nol sedikit berbeda, itu byte NUL yang digunakan untuk menandai akhir string dalam C dan panggilan sistem Unix.Jika Anda lebih tinggi dari 31, Anda akan mulai melihat karakter yang dapat dicetak, 32 adalah ruang (meskipun tidak terlalu terlihat), 33 =
!
, 34 ="
dll.Begitu,
run_ run_^A/ run_^B/
- Yang pertamarun_
sesuai dengan yang dengan byte nol, string berakhir di sana. Yang lain menunjukkan bahwa shell Anda suka menggunakan menampilkan kode kontrol^A
. Notasi juga mengisyaratkan pada fakta bahwa char dengan nilai numerik 1 dapat dimasukkan sebagai Ctrl-A, meskipun Anda perlu memberitahu shell untuk menafsirkan bukan sebagai karakter kontrol, tetapi sebagai literal, Ctrl-V Ctrl-Aharus melakukan itu setidaknya di Bash.ls:
run_ run_? run_?
-ls
tidak suka mencetak karakter yang tidak patut pada terminal, ia menggantikannya dengan tanda tanya.rsync:
run_\#003/
- yang baru bagiku, tapi idenya sama, backslash menandai pelarian, dan sisanya adalah nilai numerik dari karakter. Tampaknya bagi saya bahwa angka di sini adalah oktal, seperti pada yang lebih umum\003
.menggunakan perintah
ls | LC_ALL=C sed -n l
...run_\006$
run_\a$
run_\b$
run_\t$
-\a
,\b
dan\t
C melarikan diri untuk alarm (bel), backspace dan tab, masing-masing. Mereka memiliki nilai numerik 7, 8 dan 9, jadi harus jelas mengapa mereka datang setelah itu\006
. Menggunakan C escapes tersebut adalah cara lain untuk menandai karakter kontrol. Tanda-tanda dolar tertinggal menandai garis berakhir.Adapun
cd
, dengan asumsi asumsi saya benar,cd run_
harus pergi ke satu direktori tunggal tanpa karakter trailing aneh, dancd run_?
harus memberikan kesalahan karena tanda tanya adalah karakter gumpalan yang cocok dengan karakter tunggal, dan ada beberapa nama file yang cocok, tetapicd
hanya beberapa nama file yang cocok, tetapi hanya mengharapkan satu.Semua dari mereka, dalam arti ...
Di Bash, Anda dapat menggunakan
\000
dan\x00
keluar di dalam$'...'
tanda kutip untuk mewakili karakter khusus, jadi$'run_\033
(oktal) atau$'run_\x1b'
sesuai dengan direktori dengan nilai karakter 27 (yang kebetulan ESC). (Saya tidak berpikir Bash mendukung lolos dengan angka desimal.)jawaban cas memiliki skrip untuk mengubah nama itu, jadi saya tidak akan pergi ke sana.
sumber
ls
, ada beberapa opsi mengutip termasuk-b
/--escape
dan--quoting-style=
, atauQUOTING_STYLE
variabel lingkungan, untuk mengontrol bagaimana karakter yang tidak dicetak ditampilkan. Saya tidak berpikir ada pilihan untuk membuatnya lebih memilih oktal lolos dari versi karakter.Cara termudah adalah membuat nama file yang salah dan nama file yang benar di lingkungan yang sama di mana kecelakaan terjadi, dan kemudian hanya memindahkan / mengganti nama folder ke nama yang benar.
Untuk menghindari tabrakan antara nama yang ada, lebih baik gunakan folder tujuan lain.
Jika memungkinkan, saya lebih suka memperbaiki skrip dan menjalankannya lagi; memperbaiki beberapa bug post mortem aneh mungkin lebih mahal dan dapat menimbulkan masalah baru.
Semoga berhasil!
sumber