{
i = int(count[$4])
arr[$4,i] = $0
count[$4]++
}
END {
for (i in count) {
if (count[i]== n) {
for (j=0; j<n; j++) {
printf("%s\n", arr[i,j])
}
}
}
}
sample run --
awk -v n=3 -f 1.awk 1.dat
chr1 3007426 3007432 10
chr1 3007528 3007534 10
chr1 3007576 3007582 10
chr1 3000823 3000829 1
chr1 3001003 3001009 1
chr1 3001014 3001020 1
awk -v n=8 -f 1.awk 1.dat
chr1 3003222 3003228 4
chr1 3003335 3003341 4
chr1 3003375 3003381 4
chr1 3003578 3003584 4
chr1 3003636 3003642 4
chr1 3003717 3003723 4
chr1 3003881 3003887 4
Во-первых, не читать строки файла сfor
Я где-то читал о разбиении строк :используйте split
, когда знаете, что выбрасывать; используйте регулярное выражение, когда вы знаете, что хотите сохранить. Или что-то подобное.
Проблема с использованием разбиения слова оболочки с помощью $IFS
заключается в том, что любой символ в этой переменной используется для разбиения, и вы не можете знать, какой именно.
С помощью bash вы можете написать:
line='Hello there! How are you doing? How is life? Mine is as boring as a winter morning!'
line=${line//\?/$'"?\n'}
line=${line//\!/$'"!\n'}
echo "$line"
Hello there"!
How are you doing"?
How is life"?
Mine is as boring as a winter morning"!
Обратите внимание на начальные пробелы. Это можно обойти с помощью более сложного шаблона :line=${line//\?*([[:blank:]])/$'"?\n'}
Я бы использовал sed
вместо:
line='Hello there! How are you doing? How is life? Mine is as boring as a winter morning!'
new=$( sed 's/[?!][[:blank:]]*/&\n/g' <<<"$line" )
echo "$new"
Hello there!
How are you doing?
How is life?
Mine is as boring as a winter morning!
В awk есть функция split()
, которая позволяет захватывать разделители, но ее использование довольно многословно:
echo "$line" | awk '{
n = split($0, words, /[!?][[:blank:]]*/, seps)
for (i = 1; i < n; i++)
print words[i] seps[i]
print words[n]}
'