Я пытался использовать команды sed и awk
#!/bin/bash
i=`sed -n '1p' l.txt| awk -F "," '{print $1}'`
j=`sed -n '2p' l.txt| awk -F "," '{print $1}'`
if [[ $i == $j ]]
then
awk -F "," 'NR==2{print $2}' l.txt
else
echo "The value is different"
fi
выход
5.5
Самое основное требование выполняется через
awk '$2~/^a/{c++} END{print c+0}'
Это проверит второй столбец; проверьте, начинается ли он с a
с помощью сравнения регулярных выражений, и увеличьте счетчик c
. В конце -файла -будет напечатан счетчик. Чтобы гарантировать, что число будет напечатано, даже если c
никогда не увеличивается, мы печатаем c+0
, которое не изменится c
, если оно уже не равно -нулю, но принудительно интерпретируется как число, когда c
] все еще не инициализирован.
Теперь, чтобы убедиться, что никакие «бродячие» токены из «заголовка» не мешают, первая проверка заключается в том, чтобы убедиться, что первый столбец является целым числом:
awk '$1+0==$1 && $2~/^a/{c++} END{print c+0}'
Идея заключается в том, что $1+0
будет интерпретироваться арифметически как «ничего не добавляя», если $1
является числом, но будет указывать awk
на добавление символа 0
, если это «текст», следовательно, $1+0
не изменится, только если $1
— число.
Для еще более сложной проверки мы можем запретить рассмотрение строк до тех пор, пока не встретится строка «конец заголовка», и, кроме того, пропустить строку сразу после этого:
awk 'f==2&&$2~/^a/{c++} f==1&&NF{f++} $0=="header end"{f=1} END{print c+0}'
Это установит флаг f
в 1 при обнаружении строки header end
, установите его в 2
на первой не-пустой строке после заголовка и только в строках, где f
2
проверьте второй столбец.
Я предлагаю не awk
решение, а grep
решение, основанное на структуре записей:
$ grep "^[0-9]\+[[:blank:]]\+a[0-9]\+[[:blank:]]\+[A-Z]\+[[:blank:]]\+[A-Z]\+[[:blank:]]\+[0-9]\+$" file | wc -l
2
В соответствии с вашим описанием:подсчитайте строки, начинающиеся с a во втором столбце этого достаточно:
awk '$2 ~ /^a/ { count++ } END {print count}' file
Возможно даже, что команда grep (должна быть быстрее ):
grep -c '^[0-9][0-9]* *a' test.txt
Что также является более конкретным, поскольку требует, чтобы первое поле было числом (, предполагая, что это то, что вам нужно из примера, опубликованного ), а разделитель полей — пробел.
Но первое решение, которое вы опубликовали:
awk '/LVG/{p=$0} {a[p]++} END{for(i in a) print i"\n"a[i]-1}' file
Делает что-то совсем другое.
При вводе этого файла:
> cat file
header start
stuff
header end
pos1 LV file LVG size
1 a1 AAA BBB 100
2 b1 AAC BBB 1000
3 a3 AAB BBB 47
4 b6 AAC BBB 1000
5 c9 BBA CBA 20
pos2 LV file LVG size
1 a1 AAA BBB 100
2 b1 AAC BBB 1000
pos3 LV file LVG size
1 a1 AAA BBB 100
2 b1 AAC BBB 1000
3 a3 AAB BBB 47
Размещенный вами код выводит результат для каждого (разного )заголовка:
> awk '/LVG/{p=$0} {a[p]++} END{for(i in a) print i"=="a[i]-1}' test.txt
==2
pos1 LV file LVG size==5
pos3 LV file LVG size==3
pos2 LV file LVG size==2
То есть :2 строки для пустого заголовка, 5 строк после заголовка "pos1" и т.д....
Я не знаю, нужен ли вам такой счет или нет. Я также не понимаю, почему вы вычитаете 1 из счета.
Единственным дополнительным требованием является подсчет только тех строк, в которых второе поле начинается сa
$ awk '/LVG/{p=$0} $2 ~ /^a/ {a[p]++} END{for(i in a) print i"=="a[i]}' test.txt
pos1 LV file LVG size==2
pos3 LV file LVG size==2
pos2 LV file LVG size==1
Если вам также нужно, чтобы первое поле было числом (, аналогично команде grep выше):
$ awk '/LVG/{p=$0} ($1+0!=0)&&($2~/^a/) {a[p]++} END{for(i in a) print i"=="a[i]}' test.txt
pos1 LV file LVG size==2
pos3 LV file LVG size==2
pos2 LV file LVG size==1