Если вам нужен чистый ответ awk, который перебирает список только один раз:
awk -v count=2 'BEGIN { srand() } $3 - $2 > 3 && $3 - $2 < 10 && rand() < count / ++n { if (n <= count) { s[n] = $0 } else { s[1+int(rand()*count)] = $0 } } END { for (i in s) print s[i] }' input.txt
Сохранено в файле для удобства чтения:
BEGIN { srand() }
$3 - $2 > 3 &&
$3 - $2 < 10 &&
rand() < count / ++n {
if (n <= count) {
s[n] = $0
} else {
s[1+int(rand()*count)] = $0
}
}
END {
for (i in s) print s[i]
}
Алгоритм представляет собой небольшую вариацию алгоритма Кнута R ; Я почти уверен, что изменение не влияет на распределение, но я не статистик, поэтому не могу этого гарантировать.
Комментарий для тех, кто менее знаком с awk:
# Before the first line is read...
BEGIN {
#...seed the random number generator.
srand()
}
# For each line:
# if the difference between the second and third columns is between 3 and 10 (exclusive)...
$3 - $2 > 3 &&
$3 - $2 < 10 &&
#... with a probability of (total rows to select) / (total matching rows so far)...
rand() < count / ++n {
#... If we haven't reached the number of rows we need, just add it to our list
if (n <= count) {
s[n] = $0
} else {
# otherwise, replace a random entry in our list with the current line.
s[1+int(rand()*count)] = $0
}
}
# After all lines have been processed...
END {
# Print all lines in our list.
for (i in s) print s[i]
}
Я сделал рабочий скрипт. Поделитесь им, если кто-то найдет это полезным. Ответ @nohillside помог мне.
#!/bin/bash
count=1
while true
do
url="https://www.website.tld/page.php?var1=${count}&var2=static"
text=`curl -s "$url"`
if echo "$text" | grep -q "ERROR"
then
break
elif echo "$text" | grep -q "XYZ"
then
echo "$url" >> matches.txt
fi
((count++))
done
Было бы проще генерировать URL-адреса безcurl
:
for ((i=1; i<1000; i++)); do
url="https://www.website.tld/page.php?var1=${i}&var2=static"
if curl -s "$url" | grep -q XYZ; then
echo "$url" >> positive-matches.txt
fi
od