С помощью bash
вы можете сделать:
all=(*)
except=(file1 file2 notme.txt)
only=()
IFS=/
for file in "${all[@]}"; do
case "/${except[*]}/" in
(*"/$file/"*) ;; # do nothing (exclude)
(*) only+=("$file") # add to the array
esac
done
ls -ld -- "${only[@]}"
(это работает здесь для файлов в текущем каталоге, но не надежно для глобусов, таких как all=(*/*) кроме =(foo/bar)
, так как мы используем /
для объединения элементов массива для поиска).
Это основано на том факте, что "${array[*]}"
объединяет элементы массива с первым символом $IFS
(здесь выбрано /
иначе он не может встречаться в файле name; NUL — это символ, который не может встречаться в файле path, но, к сожалению, bash
(в отличие от zsh
) не может иметь такого символа в своих переменных). Таким образом, для каждого файла в $all
(здесь, например, $file
является foo
), мы выполняем case "/file1/file2/ notme.txt/" в (*"/foo/"*)
, чтобы проверить, следует ли исключить $file
.
Если вас интересует только временная метка пакетов, вы можете сделать снимок одного пакета в шестнадцатеричном формате и реплицировать его, изменив только временную метку, используя text2pcap
, который обычно находится в том же пакете, что и wireshark.
Например, я использовал tcpdump -XX
для захвата некоторых пакетов artibrary и выбрал короткий tcp из дампа ascii:
16:51:27.374569 IP 192.168.0.21.nut > 192.168.0.20.53910: Flags [R.]...
0x0000: b827 0099 9999 80ee 7399 9999 0800 4500 ................
0x0010: 0028 06e4 4000 4006 b272 c0a8 0015 c0a8 .(..@.@..r......
0x0020: 0014 0da5 d296 0000 0000 ee15 7872 5014 ............xrP.
0x0030: 0000 e792 0000 ......
Вы можете отфильтровать это с помощью awk, чтобы получить дамп в формате, который требуется text2pcap
, а именно:
awk '$1~/0x/ { $0 = substr($0,1,50); for(i=2;i<=9;i++)s = s $i }
END { gsub(/../,"& ",s); print "0000 " s }'
Установить переменную mypacket
на результат:
mypacket='0000 b8 27 00 99 99 99 80 ee 73 99 99 99 08 00 45 00 00 28 06 e4 40 00 40 06 b2 72 c0 a8 00 15 c0 a8 00 14 0d a5 d2 96 00 00 00 00 ee 15 78 72 50 14 00 00 e7 92 00 00'
Затем используйте другой awk, чтобы взять время из столбца 1 каждой строки вашего файла данных и добавить его к тому же пакету, сообщая программе преобразования извлечь эту отметку времени в заданном формате и преобразовать ее в подходящий формат pcap. для проводной акулы.
awk <dump -v mypacket="$mypacket" '
/79\.xxx\.xxx\.216/ { print $1 " " mypacket }' |
text2pcap -t '%H:%M:%S.' - out.pcap
Обратите внимание на последний "." в опции -t
. Это необходимо для сохранения долей секунд в отметке времени.
Текст может быть преобразован в PCAP, насколько это возможно из ограниченной информации, представленной в выводе tcpdump
, например.
#!/usr/bin/env perl
use 5.14.0;
use warnings;
use Time::Piece;
# get this from CPAN
use File::PCAP::Writer ();
my $fpw = File::PCAP::Writer->new( { fname => 'out.pcap' } );
# read tcpdump output from files or standard input
shift @ARGV if @ARGV == 1 and $ARGV[0] eq '-';
while (readline) {
my ( $stamp, $usec ) = $_ =~ m/^(\d\d:\d\d:\d\d) [.] (\d+) \s IP \s /ax;
# blindly assume packets all from the same day that is today
my $now = localtime;
$stamp = $now->ymd. ' '. $stamp;
my $epoch = Time::Piece->strptime( $stamp, "%Y-%m-%d %H:%M:%S" )->epoch;
# fake an empty packet. this gets timestamps into Wireshark,
# which may suffice to only graph packets per time
$fpw->packet( $epoch, $usec, 0, 0, '' );
}
хотя потребуется больше кода для правильной обработки меток времени, которые переносятся на следующий день (или, упс, на какую-то последующую дату? )и правильно подделывать пакеты с подсказками, указанными в выводе tcpdump
(, например. сделать фрейм, сделать IP (с IP-адресами ), сделать TCP или UDP пакет правильного размера и портов, как насчет ARP и других протоколов, и т.д. и т.п.).
Вместо пакетов в секунду из временных меток без суеты PCAP можно было бы сначала использовать эпоху -до -пакетов -, видимых -в -, что -второй сценарий:
#!/usr/bin/env perl
use 5.14.0;
use warnings;
use Time::Piece;
# start epoch
my $day = 1505199600;
my $counter = 0;
my $prev_secs = -1;
my $prev_ts;
shift @ARGV if @ARGV == 1 and $ARGV[0] eq '-';
while (readline) {
my ($hhmmss) = $_ =~ m/^(\d\d:\d\d:\d\d) [.] /ax;
my $secs = Time::Piece->strptime( $hhmmss, "%H:%M:%S" )->epoch;
# KLUGE assume next day
$day += 86400 if $secs < $prev_secs;
my $timestamp = $day + $secs;
if ( defined $prev_ts and $timestamp != $prev_ts ) {
say "$prev_ts $counter";
$counter = 0;
}
$counter++;
$prev_secs = $secs;
$prev_ts = $timestamp;
}
say "$prev_ts $counter";
А затем передайте преобразованный вывод tcpdump
в R для построения графика (Я подделал временную метку следующего дня, так как все ваши данные относятся к одной и той же секунде):
$ head -1 dumptext
20:39:12.808672 IP 94.xx.xxx.202.49183 > 151.xx.xx.xx.61479: UDP, length 104
$ tail -1 dumptext
00:31:18.123456 IP 79.xxx.xxx.216.56254 > 151.xx.xx.xx.443: Flags [P.], seq 1723903877:1723904632, ack 3204952387, win 260, length 755
$ perl torrr dumptext > dataforr
$ cat dataforr
1505273952 10
1505287878 1
$ R
> x=read.table("dataforr")
> x
V1 V2
1 1505273952 10
2 1505287878 1
> names(x)=c('date','packets')
> x$date=strptime(x$date,"%s")
> x
date packets
1 2017-09-12 20:39:12 10
2 2017-09-13 00:31:18 1
> plot(x,type='l')
>