Saya memiliki daftar panjang alamat IP, yang tidak berurutan. Saya perlu menemukan berapa banyak alamat IP yang ada sebelum / sesudah alamat IP tertentu. Bagaimana saya bisa mencapai ini?
Saya memiliki daftar panjang alamat IP, yang tidak berurutan. Saya perlu menemukan berapa banyak alamat IP yang ada sebelum / sesudah alamat IP tertentu. Bagaimana saya bisa mencapai ini?
Jawaban:
Jumlah baris sebelum dan sesudah pertandingan, termasuk pertandingan (yaitu Anda harus mengurangi 1 dari hasil jika Anda ingin mengecualikan pertandingan):
sed -n '0,/pattern/p' file | wc -l
sed -n '/pattern/,$p' file | wc -l
Tetapi ini tidak ada hubungannya dengan alamat IP pada khususnya.
Mungkin yang paling mudah adalah,
sed -n '/pattern/{=; q;}' file
Terima kasih @ JoshepR untuk menunjukkan kesalahan
dc, saya sendiri, mungkin.
Saya melakukan dua cara ini, meskipun saya pikir saya paling suka ini:
: $(( afterl=( lastl=$(wc -l <~/file) ) - 2 -
$(( beforel=( matchl=$(sed -n "/$IP/{=;q;}" <~/file) ) - 1
)) ))
for n in last match afters befores
do printf '%s line%s :\t%d\n' \
"${n%s}" "${n##*[!s]}" $((${n%s}l))
done
Itu menyimpan semua itu sebagai variabel shell saat ini - dan mengevaluasi mereka dalam for for loop kemudian untuk output. Itu menghitung total baris dalam file dengan wcdan mendapat nomor baris pertama yang cocok dengannya sed.
Keluarannya:
last line : 1000
match line : 200
after lines : 799
before lines : 199
Saya juga melakukan:
sed -n "/$IP/=;\$=" ~/file |
tr \\n \ | {
IFS=' ' read ml ll
printf '%s line%s:\t%d\n' \
last '' $((ll=${ll##* }))
match '' $ml \
after s "$((al=ll-ml-1)) \
before s $((bl=ml-1))
}
sedhanya mencetak nomor baris yang cocok dan terakhir, kemudian trmenerjemahkan \newlines yang akan diintervensi, dan readmembaca hasil pertama sedke dalam $mldan semua yang lain ke dalam $ll. Beberapa kasus pencocokan mungkin ditangani dengan melepaskan semua kecuali hasil terakhir dari $llekspansi saat mengaturnya kembali nanti.
Keluarannya:
last line : 1000
match line : 200
after lines : 799
before lines : 199
Kedua metode diuji pada file yang dihasilkan dengan cara berikut:
IP='some string for which I seek'
for count in 1 2 3 4 5
do printf '%.199d%s\n' 0 "$IP"
done | tr 0 \\n >~/file
Ya, dengan nomor baris:
"$IP"kemudian \newlinetr- yang menerjemahkan nol ke \newlines lalu ke~/fileBerikut sedikit kode Perl yang melakukannya:
perl -ne '
if(1 .. /192\.168\.1\.1/) { $before++ }
else { $after++ }
$before--; # The matching line was counted
END{print "Before: $before, After: $after\n"}' your_file
Ini menghitung jumlah total baris sebelum dan sesudah baris yang berisi IP 192.168.1.1. Ganti dengan IP yang Anda inginkan.
Hanya menggunakan Bash:
before=0
match=0
after=0
while read line;do
if [ "$line" = 192.168.1.1 ];then
match=1
elif [ $match -eq 0 ];then
before=$(($before+1))
else
after=$(($after + 1))
fi
done < your_file
printf "Before: %d, After: %d\n" "$before" "$after"
$.konter?
$afteruntuk $. - $before.
$. - 1, simpan $.ke $tmp. Cetak akhir $. - $tmp. Jadi kita tidak perlu kontra untuk sebelum dan sesudah. Tentu saja itu kurang mudah dibaca daripada milik Anda.
Saya mencoba perintah berikut, yang sedikit rumit, tetapi akan memberikan hasil yang akurat:
Setelah:
a=$(cat file | wc -l) && b=$(cat -n file | grep <Pattern> | awk '{print $1}') && echo "$a - $b" | bc -l
Sebelum:
echo "`cat -n file | grep <Pattern> | awk '{print $1}'`-1" | bc -l
Grepmemiliki fitur yang dapat menghitung berapa kali pola tertentu ditemukan. Jika Anda menggunakan -cperintah yang akan melakukannya. Dengan -cdan -vperintah, ini akan menghitung berapa kali ini tidak cocok dengan pola tertentu
Contoh:
grep -c -v <pattern> file
Jadi, jika Anda mencoba sesuatu seperti:
grep -c -v 192.168.x.x file.log itu seharusnya bekerja.