ls -1
daftar elemen saya seperti ini:
foo.png
bar.png
foobar.png
...
Saya ingin terdaftar tanpa .png
seperti:
foo
bar
foobar
...
(dir hanya berisi .png
file)
Adakah yang bisa memberi tahu saya cara menggunakannya grep
dalam kasus ini?
Tujuan: Saya memiliki file teks di mana semua nama terdaftar tanpa ekstensi. Saya ingin membuat skrip yang membandingkan file teks dengan folder untuk melihat file mana yang hilang.
.
di dalamnya. Meskipun konvensi mengatakan untuk memberi nama file Anda.png
pada akhirnya, tidak ada alasan mengapa saya tidak dapat memiliki file png bernamafoo.zip
ataumy.picture.20160518
atau hanyamypic
.ls
dan untuk mem- pipe output darils
danfind
, terutama karena kemungkinan untuk menimbulkannewline
, `tab char dalam nama file. Jika nama fileThe new art of working on .png\NEWLINE files and other formats
banyak dari solusi yang diusulkan akan menimbulkan masalah.Jawaban:
Anda hanya perlu shell untuk pekerjaan ini.
POSIXly:
Dengan
zsh
:sumber
printf
;echo ${f%.png}
akan cukup.The
sed
Menghapus perintah (yaitu, menggantikan dengan string kosong) string.png
yang ditemukan pada akhir dari nama file.Ini
.
lolos\.
sehingga ditafsirkan olehsed
sebagai.
karakter literal daripada regexp.
(yang berarti cocok dengan karakter apa pun). Ini$
adalah jangkar akhir baris, sehingga tidak cocok.png
di tengah nama file.sumber
sed 's/\.[^.]*$//'
-1
perlu, menjadi standar di sini.-1
harus ditentukan. Ini hanya default ketika pipa dihidupkan, yang merupakan kejutan tersembunyi bagi sebagian orang. Jadi, membuatnya eksplisit membantu pemahaman. Saya juga melakukan ini di skrip saya jadi saya tahu apa jenis output yang saya harapkan..png
) sebelum karakter baris baru Anda akan menghapus bahkan itu.png
dan tidak hanya yang terakhir. Lebih baik menghindari pipa dan mem-parsing output ls, itu menyimpan kejutan yang sering tersembunyi ... (beberapa kata dan referensi lebih banyak dalam jawabannya).Jika Anda hanya ingin menggunakan bash:
Anda harus meraih
grep
ketika mencoba menemukan kecocokan, bukan untuk menghapus / menggantikannyased
lebih tepat:Setelah Anda memutuskan Anda perlu membuat beberapa subdirektori untuk memesan file-file PNG Anda, Anda dapat dengan mudah mengubahnya menjadi:
sumber
find
disalurkan kesed
solusi dapat menyajikan beberapa masalah jika Anda menemukan file dengan kunci (.png
) sebagai bagian dari nama dan tepat sebelum karakter baris baru. Lebih baik untuk menghindari pipa dan mengurai outputfind
atauls
, itu menyimpan kejutan yang sering tersembunyi ... (beberapa kata dan referensi lebih dalam jawabannya).find
dengan sesuatu sepertiecho
pada contoh terakhir. Tidak jelas tujuan apa yangfind
berfungsi di sana dan hasilnya tergantung pada struktur direktori (yaitu jika Anda memiliki direktorifiles.png
)Saya akan pergi
basename
(dengan asumsi implementasi GNU):sumber
-z
(atau--zero
) untuk menghasilkan output yang dipisahkan-NUL (bukan dipisahkan-baris).Jawaban lain yang sangat mirip (saya terkejut varian khusus ini belum muncul) adalah:
-1
opsi untukls
, karenals
mengasumsikan bahwa jika output standar bukan terminal (ini adalah pipa, dalam hal ini).-n
pilihan untuksed
sarana 'tidak mencetak baris dengan default'/p
pilihan pada akhir cara substitusi '... dan mencetak baris ini jika substitusi dibuat'.Efek bersihnya adalah mencetak hanya garis-garis yang berakhir
.png
dengan.png
penghapusan. Artinya, ini juga melayani generalisasi sedikit dari pertanyaan OP, di mana direktori tidak hanya berisi.png
file.The
sed -n
Teknik ini sering berguna dalam kasus di mana Anda mungkin sebaliknya menggunakan grep + sed.sumber
.png
) sebelum char baris baru: dalam hal ini Anda akan mencetak bagian itu tanpa png, tidak hanya menghapus bagian terakhir. Sering disarankan untuk menghindari mem-parsing (dan menyalurkan) outputls
karena masalah dapat disembunyikan di tempat yang tidak Anda pikirkan ...find
atau - mungkin lebih baik - menggunakan bahasa yang lebih kuat daripadash
mengelolanya (fakta bahwash
dapat melakukan segalanya tidak berarti bahwa itu adalah pilihan terbaik di masing-masing kasus). Shell dirancang untuk kegunaan pertama.ls
, tetapi sedang terjadi masalah di masa depan. Seringkali kita membuat skrip yang akan kita gunakan nanti, ketika kita sudah akan melupakan batasnya ... (itu manusia, itu biasa). Saya mengusulkan sebuahfind
contoh (dengan-exec
dan tanpa pipa) bahkan jika saya anggap lebih baik (karena shell murni) menjawab cuonglm ini satu , solid dan POSIX compliant.locate
ataumake
pada mereka.Anda hanya dapat menggunakan perintah BASH untuk melakukan itu (tanpa alat eksternal).
Ini berguna ketika Anda tanpa / usr / bin dan berfungsi baik untuk nama file seperti this.is.image.png dan untuk semua ekstensi.
sumber
Tidaklah aman untuk menguraikan
ls
atau mengirim pipafind
[ 1 , 2 ]Tidaklah aman untuk mem-parsing (dan mem-pipe) output
ls
ataufind
, terutama karena mungkin untuk menemukan dalam nama file karakter yang tidak biasa sebagai baris baru , tab ... Di sini siklus shell murni akan bekerja [ cuonglm ] .Bahkan
find
perintah yang tidak disalurkan dengan opsi-exec
akan berfungsi:Pembaruan / Catatan : Anda dapat menggunakan
find .
bahkan untuk mencari file yang tersembunyi, ataufind ./*.png
hanya untuk mendapatkan file yang tidak tersembunyi. Denganfind *.png -exec ...
Anda dapat memiliki masalah dalam hal itu ada file bernama.png
karena find akan mendapatkannya sebagai opsi. Anda dapat menambahkan-maxdepth 0
untuk menghindari turun di direktori bernamaDir_01.png
, ataufind ./*.png -prune -exec ...
ketika maxdepth tidak diizinkan (terima kasih Stéphane). Jika Anda ingin menghindari daftar direktori tersebut, Anda harus menambahkan opsi-type f
(yang juga akan mengecualikan jenis file non-reguler lainnya). Coba lihat untukman
panorama yang lebih lengkap tentang semua opsi yang tersedia, dan ingatlah untuk memeriksa kapan mereka sesuai dengan POSIX, untuk portabilitas yang lebih baik.Beberapa kata lagi
Bisa terjadi, misalnya, bahwa menyalin judul dari dokumen dan menempelkan ke nama file, satu atau lebih baris baru akan selesai dalam nama file itu sendiri. Kita bisa sangat sial sehingga judul bisa mengandung bahkan kunci yang harus kita gunakan sebelum baris baru:
Jika Anda ingin menguji, Anda dapat membuat nama file seperti ini dengan perintah
Sederhana
/bin/ls *png
akan menampilkan?
bukan karakter yang tidak dapat dicetakDalam semua kasus di mana Anda akan pipa output dari
ls
ataufind
perintah berikut tidak akan memiliki petunjuk untuk memahami jika garis ini berasal dari baru nama berkas atau jika ia mengikuti baris baru karakter dalam preseden nama berkas . Sebuah jahat nama memang, tapi masih satu hukum.Siklus shell dengan shell Parameter-Expansion,,
${parameter%word}
dalam varian denganprintf
atauecho
akan bekerja [ cuonglm ], [ Anthon1 ] .Dari halaman manual Ekspansi Parameter Shell [ 3 ]
sumber
find
perintah Anda sedikit variabel (misalnya jika ada direktori yang disebutfiles.png
)bash 4.3.11
, lari 0,5,7-4, zsh (bila perlu) 5.0.2. Anda merasa bebas untuk membaca posting ini yang menambahkan sesuatu yang lebih. Saya setuju tentang catatan piping outputfind
, untuk ini saya sarankan-exec
, dan saya menulis dalam judul.:-)
.ls
tidak ada masalah apa pun ketika output disalurkan atau dialihkan, tetapi sebagaimana disebutkan dalam wiki mungkin tidak bekerja untuk semua. Sebagian besar hanya akan memasukkan?
menggantikan karakter khusus ketika output dikirim ke terminal. yaitu Lakukanecho *.png | od -c
danls *.png | od -c
. Masalah baris baru bukan masalah denganls
, ini masalah dengan perintah apa pun yang tidak nol berakhir di kedua sisi pipa.printf "${f%.png}\n"
salah. Argumen pertama adalah format, Anda tidak boleh menggunakan data variabel di sana. Bahkan dapat dilihat sebagai kerentanan DoS (coba dengan%1000000000s.png
file misalnya).find ./*.png -prune -exec...
atau Anda akan memiliki masalah dengan nama file yang dimulai dengan-
(dan file-file dari direktori jenis, perhatikan bahwa-maxdepth
ini tidak portabel)bukankah itu cukup?
atau secara umum, ini
akan menghapus semua ekstensi
sumber
-1
perlu, menjadi standar di sini.ls
apakah itu tetap tanpa opsi itu ketika outputnya tidak menjadi terminal, yang terjadi di sini.Gunakan
rev
:rev
membalikkan semua string (garis); Anda memotong semuanya setelah yang pertama '.' dan rev kembali sisa yang tersisa.Jika Anda ingin
grep
'alma':sumber
-1
perlu, menjadi standar di sini.My.2016.Summer.Vacation.png
cut -f 2-
.png
dan baris baru setelah ... Disarankan untuk menghindari mengurails
karena suka menyembunyikan kejutan dengan baik ... :-)Jika saya tahu direktori hanya memiliki file dengan .png sebagai ekstensi, saya hanya akan menjalankan:
ls | awk -F. '{print $1}'
Ini akan mengembalikan "bidang" pertama untuk apa pun di mana ada namafile. Ekstensi.
Contoh:
sumber
.
, sepertiImage.1.png
dan bahkan pada yang dengan nama tidak bagus , dengan karakter khusus di dalamnya. sebagai baris baru atau salah satu yang akan Anda gunakan sebagai (input) pemisah record diawk
,RS
. Disarankan untuk tidak mengurails
output karena suka menyembunyikan masalah yang akan muncul ketika Anda tidak akan mengharapkan. Anda dapat membaca lebih lanjut di referensi 1 atau 2 tersebut . BTW ide bagus untuk menggunakan awk ... Saya menaruh beberapa contoh dalam satu jawaban..
di\.
dalamsed -e 's/\.png$//'
, tapi sehingga menjadi jawaban hanya ditulis. :-( note2 Anda dapat mencoba menggunakanawk
dengan sesuatu sepertils | awk -F. '{if ($NF=="png") {for (i=1;i<NF-1;i++) printf("%s.", $i) ; printf $(NF-1)"\n"}}'
... tetapi Anda akan selalu memiliki masalah yang awk tidak tahu apakah garis itu tiba mengikuti atau tidak baris baru di dalam nama file. Saya mencoba mengatakan lebih baik dalam jawaban saya .menurut komentar Anda "Saya memiliki file teks di mana semua nama terdaftar tanpa ekstensi. Saya ingin membuat skrip PHP yang membandingkan file teks dengan folder untuk melihat file mana yang hilang":
dan sebaliknya:
sumber
ls -l | sed 's/\.png$//'
Apakah metode yang paling akurat seperti yang disorot oleh @roaima. Tanpa lolos
\.png
file bernamaa_png.png
akan terdaftar sebagai:a_
.sumber
ls -l
, seperti yang Anda lakukan, memberikan detail file, bukan itu yang ditanyakan OP.Garis shell sederhana (ksh, bash atau zsh; bukan dash):
Fungsi sederhana (dari Tanpa Ekstensi):
Atau fungsi yang menghapus ekstensi apa pun yang diberikan (png secara default):
Digunakan sebagai:
Jika outputnya adalah tanda bintang
*
, tidak ada file dengan ekstensi itu.sumber
Anda dapat mencoba umpan berikut ini untuk melihat apakah superator Anda adalah "." dan karena semua file Anda akan memiliki name.png Anda mencetak kolom pertama:
ls | awk -F"." '{print $1}'
sumber
Jika Anda memiliki akses ke sed, ini lebih baik karena akan menghapus ekstensi file terakhir, apa pun itu (png, jpg, tiff, dll ...)
sumber
this.is.a.dotty.txt
. Cobas/\.[^.]*$//
saja.