我有一个名为data.dat
的文件,其结构如下:
1: 67: 1 :s
1: 315: 1 :s
1: 648: 1 :ns
1: 799: 1 :s
1: 809: 1 :s
1: 997: 1 :ns
2: 32: 1 :s
我正在寻找的算法是:
虽然技术概念与此算法无关,但我尝试解释该问题。数据显示网络的连接表。该算法允许我们在不同的初始条件下运行它并研究这些网络的一般属性。特别是,由于删除债券的随机性,这些网络中的任何共同行为都可以被解释为基本规律。
更新:在每个步骤中生成随机数的另一个好理由是,在删除每一行后,其余行的s
/ ns
属性可能可以改变。
这是我到目前为止的代码:
#!/bin/bash
# bash in OSX
While ((#there is at least 1 s in the fourth column)); do
LEN=$(grep -c "." data.dat) # number of lines
RAND=$((RANDOM%${LEN}+1)) # generating random number
if [[awk -F, "NR==$RAND" 'data.dat' | cut -d ':' -f 4- == "s"]]; then
sed '$RANDd' data.txt
else
#go back and produce another random
done
exit
我尝试使用awk -F, "NR==$RAND" 'data.dat' | cut -d ':' -f 4-
找到第四列,并按sed '$RANDd' data.txt
删除该行。
s
对? if
中的条件是否正确。 else
之后强行循环以返回生成另一个随机数。谢谢,
我非常感谢你的帮助。
答案 0 :(得分:0)
#!/usr/bin/env perl
# usage: $ excise.pl < data.dat > smaller_data.dat
my $sampleLimit = 10; # sample up to ten lines before printing output
my $dataRef;
my $flagRef;
while (<>) {
chomp;
push (@{$dataRef}, $_);
push (@{$flagRef}, 1);
}
my $lineCount = scalar @elems;
my $sampleIndex = 0;
while ($sampleIndex < $sampleLimit) {
my $sampleLineIndex = int(rand($lineCount));
my @sampleElems = split("\t", $dataRef->[$sampleLineIndex];
if ($sampleElems[3] == "s") {
$flagRef->[$sampleLineIndex] = 0;
}
$sampleIndex++;
}
# print data.dat to standard output, minus any sampled lines that had an 's' in them
foreach my $lineIndex (0..(scalar @{$dataRef} - 1)) {
if ($flagRef->[$lineIndex] == 1) {
print STDOUT $dataRef->[$lineIndex]."\n";
}
}
答案 1 :(得分:0)
就个人而言,我建议不要在bash中这样做,除非你绝对没有选择。
这是你在Perl中做到的另一种方式(功能与Alex's answer非常相似,但有点简单):
use strict;
use warnings;
my $filename = shift;
open my $fh, "<", $filename or die "could not open $filename: $!";
chomp (my @lines = <$fh>);
my $sample = 0;
my $max_samples = 10;
while ($sample++ < $max_samples) {
my $line_no = int rand @lines;
my $line = $lines[$line_no];
if ($line =~ /:s\s*$/) {
splice @lines, $line_no, 1;
}
}
print "$_\n" for @lines;
用法:perl script.pl data.dat
将文件读入数组@lines
。从数组中选择一个随机行,如果它以:s结尾(后跟任意数量的空格),则将其删除。最后打印剩余的行。
这可以满足您的需求,但我应该警告您,依赖任何语言的内置随机数生成器并不是获得统计上显着结论的好方法。如果您需要高质量的随机数,则应考虑使用Math::Random::MT::Perl之类的模块来生成它们,而不是使用内置的rand
。
答案 2 :(得分:0)
NumLine=$( grep -c "" data.dat )
while [ ${NumLine} -gt ${TargetLine} ]
do
# echo "Line at start: ${NumLine}"
RndLine=$(( ( ${RANDOM} % ${NumLine} ) + 1 ))
RndValue="$( echo " ${RANDOM}" | sed 's/.*\(.\{6\}\)$/\1/' )"
sed "${RndLine} {
s/^\([^:]*:\)[^:]*\(:.*:ns$\)/\1${RndValue}\2/
t
d
}" data.dat > /tmp/data.dat
mv /tmp/data.dat data.dat
NumLine=$( grep -c "" data.dat )
#cat data.dat
#echo "- Next Iteration -------"
done
在AIX上测试(所以不是GNU sed)。在Linux下,使用--posix
作为sed选项,在这种情况下,您可以使用-i
代替临时文件+重定向+移动
不要忘记RANDOM
不是真正的RANDOM所以基于非随机值的网络行为研究无法反映特定情况下的现实