Saya memiliki file-file berikut:
Codigo-0275_tdim.matches.tsv
Codigo-0275_tdim.snps.tsv
FloragenexTdim_haplotypes_SNp3filter17_single.tsv
FloragenexTdim_haplotypes_SNp3filter17.tsv
FloragenexTdim_SNP3Filter17.fas
S134_tdim.alleles.tsv
S134_tdim.snps.tsv
S134_tdim.tags.tsv
Saya ingin menghitung jumlah file yang memiliki kata snp
(sensitif huruf) pada namanya. Saya mencoba menggunakan
grep -a 'snp' | wc -l
tapi kemudian saya menyadari bahwa grep
pencarian di dalam file. Apa perintah yang benar untuk memindai melalui nama file?
Jawaban:
Apakah Anda bermaksud mencari nama
snp
file ? Itu akan menjadi shell glob sederhana (wildcard), digunakan seperti ini:Abaikan
-q
bendera jika versils
Anda tidak mengenalinya. Ini menangani nama file yang mengandung karakter "aneh" (termasuk baris baru).sumber
ls
untuk mengambil nama file dengan teks tertentu di dalamnya. Tapi itu berhasil, terima kasih.ls
cocok dengan nama file, itu shell.ls
melihat daftar file yang cocok dengan polanya; itu tidak melihat pola itu sendiri.Jika Anda berdiri diam di lorong-lorong Unix & Linux dan mendengarkan dengan seksama, Anda akan mendengar suara hantu, meratap sedih, "Bagaimana dengan nama file yang mengandung baris baru?"
atau, secara setara ,
akan menampilkan semua nama file yang berisi
snp
, masing-masing diikuti oleh baris baru, tetapi juga termasuk baris baru dalam nama file , dan kemudian menghitung jumlah baris dalam output. Jika ada file yang namanyaf o o s n p \n b a r . t s v
maka nama itu akan ditulis sebagai
yang, tentu saja, akan dihitung sebagai dua baris.
Ada beberapa alternatif yang lebih baik dalam setidaknya beberapa kasus:
yang menghitung garis yang berisi
snp
, jadifoosnp(\n)bar.tsv
contoh dari di atas hanya dihitung satu kali. Sedikit variasi dalam hal ini adalahDua perintah di atas berbeda karena:
ls -f
akan mencakup file yang namanya dimulai dengan.
; yangprintf … *
tidak, kecualidotglob
opsi shell diatur.printf
adalah shell builtin;ls
adalah perintah eksternal. Oleh karena itu,ls
mungkin menggunakan sumber daya sedikit lebih.*
, ia mengurutkan nama file;ls -f
tidak mengurutkan nama file. Oleh karena itu,ls
mungkin menggunakan sumber daya sedikit lebih sedikit.Tetapi mereka memiliki sesuatu yang sama: mereka berdua akan memberikan hasil yang salah di hadapan nama file yang mengandung baris baru dan memiliki
snp
keduanya sebelum dan sesudah baris baru .Lain:
Ini membuat variabel array shell yang mencantumkan semua nama file yang berisi
snp
, dan kemudian melaporkan jumlah elemen dalam array. Nama file diperlakukan sebagai string, bukan baris, jadi baris baru yang disematkan tidak menjadi masalah. Bisa dibayangkan bahwa pendekatan ini dapat memiliki masalah jika direktori sangat besar, karena daftar nama file harus disimpan dalam memori shell.Lagi:
Sebelumnya, ketika kami mengatakan
printf "%s\n" *snp*
,printf
perintah mengulang (menggunakan kembali)"%s\n"
format string sekali untuk setiap argumen dalam perluasan*snp*
. Di sini, kami membuat perubahan kecil dalam hal itu:Ini akan mengulang (menggunakan kembali)
"%.0s\n"
format string sekali untuk setiap argumen dalam perluasan*snp*
. Tetapi"%.0s"
berarti untuk mencetak nol karakter pertama dari setiap string - yaitu, tidak ada. Iniprintf
perintah akan menampilkan hanya baris baru (yaitu, baris kosong) untuk setiap file yang berisisnp
namanya; dan kemudianwc -l
akan menghitungnya. Dan, sekali lagi, Anda dapat memasukkan.
file dengan pengaturandotglob
.sumber
Abstrak:
Bekerja untuk file dengan nama "ganjil" (termasuk baris baru).
Deskripsi
Sebagai gumpalan sederhana akan cocok dengan setiap nama file dengan
snp
namanya gampangecho *snp*
saja sudah cukup untuk kasus ini, tetapi untuk benar-benar menunjukkan bahwa hanya ada tiga file yang cocok yang akan saya gunakan:Satu-satunya masalah yang tersisa adalah untuk menghitung file. Ya, grep adalah solusi biasa, dan ya menghitung baris baru dengan
wc -l
juga merupakan solusi biasa. Perhatikan bahwagrep -c
(hitungan) benar-benar menghitung berapa kali suatusnp
string cocok, dan, jika satu nama file memiliki lebih dari satusnp
string dalam nama, hitungannya akan salah.Kita bisa melakukan yang lebih baik.
Salah satu solusi sederhana adalah dengan mengatur argumen posisi:
Untuk menghindari mengubah argumen posisi kita dapat mengubah setiap argumen menjadi satu karakter dan mencetak panjang string yang dihasilkan (untuk sebagian besar shell):
Atau, dalam bash, untuk menghindari subkulit:
Daftar file
Daftar file (dari pertanyaan asli dengan satu dengan baris baru ditambahkan):
Itu akan memiliki file dengan satu baris baru di tengah:
f o o s n p \n b a r . t s v
Dan untuk menguji ekspansi glob:
Itu akan menambahkan tanda bintang, yang, jika tidak dikutip, akan diperluas ke seluruh daftar file.
sumber
katakanlah Anda ingin menghitung jumlah file html:
jadi jika Anda menghitung kemunculan "snp":
sumber