Saya memiliki file bernama yang Element_query
berisi hasil dari permintaan:
SQL> select count (*) from element;
[Output of the query which I want to keep in my file]
SQL> spool off;
Saya ingin menghapus baris 1 dan baris terakhir menggunakan perintah shell.
Jawaban:
Menggunakan GNU
sed
:Bagaimana itu bekerja :
-i
opsi edit file itu sendiri. Anda juga bisa menghapus opsi itu dan mengarahkan output ke file baru atau perintah lain jika Anda mau.1d
menghapus baris pertama (1
hanya untuk bertindak pada baris pertama,d
untuk menghapusnya)$d
menghapus baris terakhir ($
hanya untuk bertindak pada baris terakhir,d
untuk menghapusnya)Lebih jauh:
1,5d
akan menghapus 5 baris pertama.SQL>
menggunakan pernyataan/^SQL> /d
/^$/d
statement1;statement2;satement3;...
) atau dengan menentukannya secara terpisah pada baris perintah (-e 'statement1' -e 'statement 2' ...
)sumber
1,3d
akan menghapus tiga baris pertama) tetapi sedikit lebih sulit untuk akhirnya. Tergantung pada apa yang Anda inginkan, Anda bisa lebih baik menggunakan ini:sed -i '/^SQL> /d' Element_query
untuk menghapus baris yang dimulaiSQL>
tanpa peduli di mana file itu berada.sed
satu-liner - yang akan bekerja untuk menghilangkan jumlah baris sewenang-wenang dari kepala dan ekor file, Lebih baik, selama input adalah file biasa, hanya untuk mengelompokkan satu input tunggal di duahead
proses - itu adalah Cara tercepat untuk melakukan ini biasanya.sed -i '1d' table-backup.sql
menghapus baris pertama file teks sqlkepala; kepala
Dengan di atas, Anda dapat menentukan jumlah baris pertama yang akan dilepas dari kepala keluaran dengan
head
perintah pertama , dan jumlah baris yang akan ditulisoutfile
dengan yang kedua. Biasanya juga akan melakukan ini lebih cepat daripadased
- terutama ketika input besar - meskipun membutuhkan dua doa. Manased
pasti harus lebih disukai meskipun, adalah dalam hal<infile
ini tidak biasa, lseekable berkas - karena ini biasanya akan tidak bekerja sebagaimana dimaksud dalam kasus itu, namunsed
dapat menangani semua modifikasi output dalam proses tunggal, scripted.Dengan GNU
head
Anda bisa menggunakan-
formulir negatif untuk[num]
di perintah kedua juga. Dalam hal ini perintah berikut akan menghapus baris pertama dan terakhir dari input:ATAU dengan POSIX
sed
:Katakan, misalnya, saya membaca input 20 baris dan saya ingin menghapus 3 dan 7 yang terakhir. Jika saya memutuskan untuk melakukannya dengan
sed
, saya akan melakukannya dengan buffer ekor. Pertama-tama saya akan menambahkan tiga dan tujuh untuk jumlah total strip dan kemudian melakukan:Itu adalah contoh yang menghapus 3 baris pertama dan 7 baris terakhir dari input. Idenya adalah bahwa Anda dapat menyangga sebanyak mungkin garis yang ingin Anda lepas dari ujung input di ruang pola pada tumpukan tetapi hanya
P
memotong yang pertama untuk setiap baris yang ditarik.1,10
sed
P
tidak ada apapun karena untuk masing-masing input susun dalam ruang pola garis-demi-baris dalamb
loop peternakan.sed
tumpukand
dihapus - dan sehingga 3 baris pertama dilepaskan dari output dalam satu gerakan.sed
mencapai$
baris input terakhir dan mencoba menarikN
ext, hits EOF dan berhenti memproses seluruhnya. Tetapi pada saat itu, ruang pola mengandung semua garis14,20
- tidak ada yang belumP
dirusak, dan tidak pernah ada.sed
P
jalankan hanya hingga baris pertama yang terjadi\n
di ruang pola, danD
hapus yang sama sebelum memulai siklus baru dengan apa yang tersisa - atau 6 baris input berikutnya. Baris ke-7 ditambahkan lagi ke stack denganN
perintah ext dalam siklus baru.Jadi, dari
seq
output (yaitu 20 baris bernomor berurutan) ,sed
hanya mencetak:Ini menjadi bermasalah ketika jumlah garis yang ingin Anda lepas dari buntut input besar - karena
sed
kinerja berbanding lurus dengan ukuran ruang pola. Namun, tetap saja, ini adalah solusi yang layak dalam banyak kasus - dan POSIX menentukansed
ruang pola untuk menangani setidaknya 4kb sebelum penghancuran.sumber
tail
juga mendukungtail -n+<num>
sintaks yang diperluas yang berarti "mulai dari baris<num>
"Saya tidak akan menjawab cara menghapus sejumlah baris. Saya akan menyerang masalah dengan cara ini:
grep -v '#SQL>' Element_query >outfile
Alih-alih menghitung baris, ini menghilangkan perintah SQL dengan mengenali petunjuknya. Solusi ini kemudian dapat digeneralisasi untuk file output lain dari sesi SQL dengan lebih banyak perintah daripada hanya dua.
sumber
ed
adalah 'editor teks standar' dan harus tersedia pada sistem yang tidak memiliki GNUsed
. Ini awalnya dirancang sebagai editor teks, tetapi sangat cocok untuk skrip.1d
menghapus baris pertama file,$d
(dikutip agar shell tidak menganggap itu variabel) menghapus baris terakhir,w
menulis file danq
berhentied
.printf
di sini digunakan untuk memformat perintah untuked
- masing-masing harus diikuti oleh baris baru; tentu saja ada cara lain untuk mencapai hal ini.sumber
Ada beberapa cara untuk menghapus baris awal dan akhir dari file.
Anda dapat menggunakannya
awk
karena menangani pencocokan pola dan penghitungan garis,Anda dapat menggunakan
grep -v
untuk mengecualikan garis yang tidak Anda inginkan berdasarkan pola, dan Anda dapat mencocokkan beberapa pola menggunakan-E
opsi,Anda dapat menggunakan
head
dantail
untuk memangkas jumlah garis tertentu,Anda dapat menggunakan
vi/vim
, dan menghapus baris pertama dan terakhir,Anda bisa menggunakan skrip perl, lewati baris pertama, simpan setiap baris, cetak ketika Anda mendapatkan baris berikutnya,
sumber
head
Anda tidak benar-benar membutuhkan pipa, dan, sebenarnya lebih baik tidak menggunakannya sama sekali jika Anda bisa lolos begitu saja. Ketika Anda melakukannyahead | head
- sementara kedua proses dapat berjalan secara bersamaan, keduanya juga memproses hampir semua data yang sama secara berlebihan. Jika Anda melakukannya,{ head >dump; head >save; } <in
Anda hanya melompat dengan offset - yang pertama membaca 10 baris ke>dump
dan yang kedua membaca 10 baris berikutnya ke>save
.Anda akan jauh lebih baik dilayani dengan memotong perintah SQL. Anda dapat melakukan ini dengan dua cara:
Jika Anda benar - benar yakin bahwa urutan "
SQL>
" tidak terjadi di tempat lain di output,Jika Anda tidak yakin,
Versi kedua lebih lambat tetapi lebih akurat: ia akan mengabaikan baris yang diawali dengan "SQL>" dan berakhir dengan titik koma, yang sepertinya menggambarkan garis yang ingin Anda hapus.
Namun, akan lebih baik untuk tidak memasukkan output ekstra dalam file untuk memulai. Sebagian besar sistem SQL memiliki beberapa cara untuk melakukan itu. Saya tidak terlalu fasih dengan Oracle, tapi mungkin jawaban ini mungkin bisa membantu.
sumber
Anda dapat memilih garis antara rentang dalam
awk
(ini mengasumsikan Anda tahu berapa banyak garis yang ada):Atau di Perl:
Jika Anda tidak tahu berapa banyak garis yang ada, Anda dapat menghitungnya dengan cepat menggunakan
grep
(perhatikan bahwa ini tidak akan menghitung garis kosong, gunakan jugagrep -c '' file
untuk menghitungnya):sumber
Coba solusi ini:
Kustomisasi
Anda dapat dengan mudah mengadaptasinya untuk menghapus dan mengubah baris pertama
+2
daritail
;atau untuk menghapus n baris terakhir mengubah
-1
darihead
.sumber
Menggunakan
awk
:< inputfile
: Pengalihan isiinputfile
untukawk
'sstdin
> outputfile
: Pengalihan isiawk
'sstdout
untukoutputfile
NR>1
: menjalankan tindakan berikut hanya jika jumlah catatan yang diproses lebih besar dari 1{print r}
: mencetak konten variabelr
{r=$0}
: menetapkan konten catatan yang sedang diproses ke variabelr
Jadi pada saat eksekusi pertama
awk
skrip, blok aksi pertama tidak dieksekusi, sedangkan blok aksi kedua dieksekusi dan konten rekaman ditugaskan ke variabelr
; pada eksekusi kedua, blok aksi pertama dieksekusi, dan konten variabelr
dicetak (sehingga catatan sebelumnya dicetak); ini memiliki efek mencetak setiap baris yang diproses tetapi yang pertama dan yang terakhir.sumber
r
.