Macos 迭代和有条件地删除文件中的行 简介
我有一个名为Macos 迭代和有条件地删除文件中的行 简介,macos,bash,random,awk,sed,Macos,Bash,Random,Awk,Sed,我有一个名为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 算法 我正在寻找的算法是: 在此文件中生成一个介于1和行数之间的随机数 如果第四列为“s”,则删除该行 否则,生成另一个随
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':'-f4-
查找第四列,并通过sed'$RAND'data.txt
删除该行
问题
s
对李>
if
中的条件是否正确李>
else
之后的循环返回以生成另一个随机数#/usr/bin/env perl
#!/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";
}
}
#用法:$exerce.plsmaller\u data.dat
我的$sampleLimit=10;#打印输出前,最多采样10行
我的$dataRef;
我的$flagRef;
而(){
咀嚼;
推送(@{$dataRef},$\;
push(@{$flagRef},1);
}
my$lineCount=标量@elems;
my$sampleIndex=0;
而($sampleIndex<$sampleLimit){
我的$sampleLineIndex=int(兰特($lineCount));
my@sampleElems=split(“\t”,$dataRef->[$sampleLineIndex];
如果($sampleElems[3]=“s”){
$flagRef->[$sampleLineIndex]=0;
}
$sampleIndex++;
}
#将data.dat打印到标准输出,减去其中包含“s”的任何采样行
foreach my$lineIndex(0..(标量@{$dataRef}-1)){
如果($flagRef->[$lineIndex]==1){
打印STDOUT$dataRef->[$lineIndex]。“\n”;
}
}
就我个人而言,我建议不要在bash中这样做,除非你别无选择
下面是另一种在Perl中实现的方法(在功能上与Perl非常相似,但更简单):
使用严格;
使用警告;
我的$filename=shift;
打开我的$fh,”
在AIX上测试(因此不是GNU-sed)。在Linux下,对sed选项使用--posix
,在这种情况下,您可以使用-i
代替临时文件+重定向+移动
不要忘记,RANDOM
不是一个真正的随机值,因此基于非随机值的网络行为研究不能反映一个实际情况,而不是一个特定的案例您正在删除以“:s”结尾的每一行"。为什么要费心处理随机数和迭代?这听起来可能有点技术性,但这是一个我感兴趣的网络,在随机移除键的情况下,它的渗透性和灵活性。@JohnB:我知道最快的方法是移除所有带有s
的线条,但这只是研究的一部分。今后,我打算研究这些网络达到特定阈值前的ks(无s).基本上,如果我能运行这个,我有一个程序可以运行任何最后数量的s
行。另外,随机删除行以避免任何有偏差的结果也很重要。也许最好用细节更新您的问题,以准确证明网络研究需要随机
。此外,还有许多语法e您的代码中有错误。可能会有帮助。我想知道,您尝试过任何答案吗?
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;
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