Saya memiliki file Log yang perlu diuraikan dan dianalisis. File berisi sesuatu yang mirip seperti di bawah ini:
Mengajukan:
20141101 server contain dump
20141101 server contain nothing
{uekdmsam ikdas
jwdjamc ksadkek} ssfjddkc * kdlsdl
sddsfd jfkdfk
20141101 server contain dump
Berdasarkan skenario di atas, saya harus memeriksa apakah baris awal tidak mengandung tanggal atau Nomor saya harus tambahkan ke baris sebelumnya.
Berkas keluaran:
20141101 server contain dump
20141101 server contain nothing {uekdmsam ikdas jwdjamc ksadkek} ssfjddkc * kdlsdl sddsfd jfkdfk
20141101 server contain dump
text-processing
sed
awk
William R
sumber
sumber
-0
jika untuk catatan yang dibatasi NUL. Gunakan-0777
untuk menyeruput seluruh file dalam memori (yang Anda tidak perlu di sini).Mungkin sedikit mudah
sed
bagian pertama
:1;N;$!b1
kumpulkan semua baris dalam file dibagi dengan\n
dalam 1 baris panjangbagian kedua lepaskan simbol baris baru jika mengikuti simbol non-digit dengan spasi yang mungkin di antara simbol tersebut.
Untuk menghindari batasan memori (terutama untuk file besar), Anda dapat menggunakan:
Atau lupakan
sed
skrip yang sulit dan untuk mengingat tahun itu dimulai2
sumber
tr '\n' $'\a' | sed $'s/\a\a*\( *[^0-9]\)/\1/g' | tr $'\a' '\n'
sendiri.+
adalah ERE\{1,\}
.[\n]
juga tidak portabel.\n\{1,\}
akan menjadi POSIX.: 1;x
adalah mendefinisikan1;x
label pada sed POSIX. Jadi, Anda perlu:sed -e :1 -e 'N;$!b1' -e 's/\n\{1,\}\( *[^0-9]\)/\1/g'
. Perhatikan juga bahwa banyaksed
implementasi memiliki batasan kecil pada ukuran ruang pola mereka (POSIX hanya menjamin 10 x LINE_MAX IIRC).Salah satu caranya adalah:
Namun, itu juga menghapus baris terakhir. Untuk menambahkannya lagi, gunakan:
Penjelasan
The
-l
akan menghapus trailing baris (dan juga menambahkan satu ke setiapprint
panggilan yang mengapa saya menggunakanprintf
sebagai gantinya. Kemudian, jika baris saat ini dimulai dengan angka (/^\d+/
) dan nomor baris saat ini lebih besar dari satu ($.>1
, ini diperlukan untuk menghindari menambahkan ekstra baris kosong di awal), tambahkan a\n
ke awal baris.printf
Mencetak setiap baris.Atau, Anda dapat mengubah semua
\n
karakter menjadi\0
, lalu mengubah karakter\0
yang tepat sebelum serangkaian angka\n
lagi:Untuk membuatnya hanya cocok dengan string 8 angka, gunakan ini sebagai gantinya:
sumber
printf
adalah format . Useprintf "%s", $_
%10000000000s
misalnya.perl
,echo %.10000000000f | perl -ne printf
membawa mesin saya ke lutut.Coba lakukan ini menggunakan awk :
Untuk menggunakannya:
sumber
Cara lain yang paling sederhana (daripada jawaban saya yang lain) menggunakan algoritma awk dan terdon :
sumber
END{print ""}
. Alternatif:awk -v ORS= 'NR>1 && /^[0-9]{8}/{print "\n"};1;END{print "\n"}'
sumber
Program id bash:
dalam bentuk satu baris:
Solusi dengan backslashes preserving (
read -r
) dan spasi terkemuka (hanyaIFS=
setelahwhile
):bentuk satu baris:
sumber
n
. Ini juga menghapus spasi. Tetapi Anda dapat menggunakannyamksh
untuk melakukan ini:while IFS= read -r L; do [[ $L = [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]* ]] && print; print -nr -- "$L"; done; print
Itu akan bekerja
sumber