Я просто пишу несколько строк для поиска наименьшего значения в моих файлах, и это дает мне правильный результат, но повторяя строки два раза, вы можете исправить ошибку
Что я делаю:
Скрипт:
#!/bin/bash
for i in `ls -v *.txt`
do
smallestPValue=`sed 1d $i | sort -k9 -g | head -1 | awk '{print $0}'`
echo $i $smallestPValue >> smallesttPvalueAll.txt
done
output
U1.text 4 rsxxx 1672175 A ADD 759 0.0751 4.918 1.074e-06
U1.txt 4 rsxxxx 1672175 A ADD 759 0.0751 4.918 1.074e-06
U2.txt 16 rsxxxx 596342 T ADD 734 -0.05458 -5.204 2.535e-07
U2.txt 16 rsxxxx 596342 T ADD 734 -0.05458 -5.204 2.535e-07
U3.txt 2 rsxxxx 12426 T ADD 722 0.06825 5.285 1.669e-07
Я получаю повторения для нескольких строк, а некоторые просто в порядке поскольку U3, как указано выше, придет один раз, и это то, что я хочу. Я могу легко избавиться от повторяющихся строк с помощью uniq или sort -u, но мне интересно, что вызывает это
Желаемый результат каждая строка повторяется один раз
Если я правильно интерпретирую, вы, вероятно, сможете сделать то, что пытаетесь сделать, просто awk
иsort
-без необходимости в цикле или синтаксический анализ ls(тонкий намек:НЕ ДЕЛАЙТЕ ЭТОГО! ), или head
, или sed
.
awk 'FNR > 1 {print FILENAME, $0}' *.txt | sort -k10 -g | sort -u -k1,1
Это пропускает первую строку каждого файла, затем печатает все оставшиеся строки с префиксом имени файла и пробелом. (Разделитель выходных записей awk по умолчанию илиORS
). Затем он передает его через сортировку, чтобы выполнить общую числовую сортировку по полю 10. Наконец, он выполняет уникальную сортировку только первого поля (-k1,1
, имени файла ), так что выводится только первая строка с этим именем файла.
Обратите внимание, что здесь мы должны сортировать по полю 10, а не по полю 9, потому что мы добавили имя файла в качестве первого поля, поэтому номера всех остальных полей увеличиваются на 1.
FNR
и FILENAME
построены -в переменных awk. FNR — это номер строки («номер входной записи» в awk -жаргоне )текущего файла, а FILENAME — это имя текущего файла.
вот еще один способ сделать это, на этот раз используя толькоawk
:
#!/usr/bin/awk -f
FNR > 1 && (! s[FILENAME] || $9 < s[FILENAME]) {
s[FILENAME]=$9;
l[FILENAME]=$0
};
END {
for (f in s) {
print f, l[f]
}
}
сохранить как, например. smallest-pvalue.awk
, сделайте его исполняемым с помощью chmod +x smallest-pvalue.awk
и запустите как ./smallest-pvalue.awk *.txt
.
Этот awk-скрипт отслеживает наименьшее значение поля 9 каждого входного файла в массиве с именем s
, а также сохраняет соответствующую входную строку в массиве l
.
После обработки всех файлов он выводит имя файла и строку, содержащую наименьшее 9-е поле для каждого файла.