Saya mencoba mendapatkan baris tertentu dari file teks.
Sejauh ini, secara online saya hanya melihat hal-hal seperti sed, (Saya hanya dapat menggunakan sh -not bash atau sed atau semacamnya). Saya perlu melakukan ini hanya dengan menggunakan skrip shell dasar.
cat file | while read line
do
#do something
done
Saya tahu cara mengulang melalui garis, seperti yang ditunjukkan di atas, tetapi bagaimana jika saya hanya perlu mendapatkan konten dari baris tertentu
cat
oke tapised
tidak? Itu tidak masuk akal.cat
. Aw ... imutcat
!Jawaban:
sed:
awk:
sumber
5!d
berarti hapus semua baris kecuali 5. shell var dimungkinkan, Anda perlu tanda kutip ganda.sed -n 5p
Ini tampaknya lebih logis untuk diingat untuk pemula, karena-n
berarti "tidak ada keluaran secara default" danp
singkatan dari "print", dan tidak ada penyebutan penghapusan yang berpotensi membingungkan (ketika orang membicarakan file, menghapus baris cenderung berarti sesuatu yang berbeda).-n '5p'
bekerja untuk masalah ini juga. Perbedaannya di sini adalah, dengan5!d
Anda dapat menambahkan-i
untuk menulis perubahan kembali ke file. Namun, dengan-n 5p
Anda harus melakukannyased -n '5p' f > f2&& mv f2 f
lagi, untuk pertanyaan ini, saya setuju dengan pendapat Anda.Dengan asumsi
line
adalah variabel yang menyimpan nomor baris yang Anda butuhkan, jika Anda dapat menggunakanhead
dantail
, maka itu cukup sederhana:Jika tidak, ini seharusnya berhasil:
sumber
-eq
perbandingan untuk bilangan bulat, sehingga ingin nomor baris, tidak puas baris ($line
). Ini harus diperbaiki dengan mendefinisikan misalnyawant=5
sebelum pengulangan, dan kemudian menggunakan-eq
perbandingan pada$want
. [dipindahkan dari suntingan yang ditolak]Anda bisa menggunakan
sed -n 5p file
.Anda juga bisa mendapatkan rentang, misalnya
sed -n 5,10p file
.sumber
Metode kinerja terbaik
Karena
sed
berhenti membaca baris apa pun setelah baris ke-5Perbarui eksperimen dari Tn. Roger Dueck
sumber
sed -n 5q
sed
berhenti membaca baris apa pun setelah baris ke-5.sed -n 1p /usr/share/dict/words
sertased '1q;d' /usr/share/dict/words
menggunakantime
perintah; yang pertama mengambil 0,043 detik, yang kedua hanya 0,002, jadi menggunakan 'q' jelas merupakan peningkatan kinerja!Jika misalnya Anda ingin mendapatkan baris 10 hingga 20 dari sebuah file, Anda dapat menggunakan masing-masing dari dua metode ini:
atau
p
di atas perintah berarti pencetakan.Inilah yang akan Anda lihat:
sumber
Cara standar untuk melakukan hal semacam ini adalah dengan menggunakan alat eksternal. Melarang penggunaan alat eksternal saat menulis skrip shell tidak masuk akal. Namun, jika Anda benar-benar tidak ingin menggunakan alat eksternal, Anda dapat mencetak baris 5 dengan:
Perhatikan bahwa ini akan mencetak baris logis 5. Artinya, jika
input-file
berisi garis lanjutan, mereka akan dihitung sebagai satu baris. Anda dapat mengubah perilaku ini dengan menambahkan-r
ke perintah baca. (Yang mungkin merupakan perilaku yang diinginkan.)sumber
$((++i))
tampaknya menjadi bashism; jika OP dibatasi dalam menggunakan alat eksternal, saya tidak akan berasumsi mereka akan memiliki akses ke lebih dari sekadar/bin/sh
++
peningkatan secara khusus ditandai sebagai opsional).$((i+=1))
bekerja di Dash juga.$(($i+1))
adalah solusi sederhana yang saya pikirkan.Sejalan dengan jawaban William Pursell , berikut adalah konstruksi sederhana yang harus bekerja bahkan di shell Bourne v7 asli (dan dengan demikian juga tempat-tempat di mana Bash tidak tersedia).
Perhatikan juga optimasi untuk
break
keluar dari loop ketika kita telah mendapatkan garis yang kita cari.sumber
Saya tidak terlalu menyukai jawaban apa pun.
Inilah cara saya melakukannya.
sumber
Mudah dengan perl! Jika Anda ingin mendapatkan baris 1, 3 dan 5 dari sebuah file, katakan / etc / passwd:
sumber
seq 5 | perl -ne 'print if $. ~~ [1, 4, 5]'
tetapi smartmatch bersifat eksperimental dan penggunaannya tidak disarankansumber
sed -n 5p
, yang tentu saja masih dapat dioptimalkan untuk sesuatu sepertised -n '5!d;p;q'