Вы можете взглянуть на то, насколько FAITE делает это здесь .
Как сказал Ян, lsb_release, вероятно, лучше всего пойти, но это не может быть вашим единственным способом. Например, LSB_Release по умолчанию не присутствует на любом из моих серверов RHEL:
[damaya@damaya-sandbox script]$ lsb_release
-bash: lsb_release: command not found
[damaya@damaya-sandbox script]$ yum provides "*/lsb_release"
redhat-lsb-core-4.0-7.el6.centos.i686 : LSB base libraries support for CentOS
Repo : base
Matched from:
Filename : /usr/bin/lsb_release
так, если LSB_Release нет в системе, то ваш следующий шаг - получить информацию из файла / etc / * - выпуска. Однако, если это также не присутствует в системе, то вы не повезете. К сожалению, не существует 100% надежный способ получить эту информацию.
Вот решение awk
, которое выходит из-под контроля, чтобы предотвратить печать второго a
:
awk '$1 == "a" { if (!head) print; n=head=1; next } $1 !~ /^[0-9]/ { n=0 } n' ascii_file
Замените "a"
на "b"
, чтобы получить эти результаты и т.д. Выход:
Выход:
a
1 2 3
1223
4 5
Если бы Вам нужен был цикл, Вы могли бы сделать это следующим образом:
for letter in a b c; do
echo
awk -v letter="$letter" '$1 == letter { if (!head) print; n=head=1; next } $1 !~ /^[0-9]/ { n=0 } n' /tmp/a
done
, в результате чего получился бы этот выход:
a
1 2 3
1223
4 5
b
1 2 3 5
3344
1223
c
1 2 34
123
(Обратите внимание на строку echo
. Это разделяет хиты каждого запроса. Я структурировал этот ответ так, чтобы вы могли сделать запрос на каждую букву, что в моем понимании этого вопроса)
Ах, awk
делает вещи намного проще, используя только один проход через данные, в отличие от других решений, которые я видел здесь до сих пор:
/^[a-z]/{key=$0;}
/^[0-9]/{if (key in res){ res[key]=res[key] "\n" $0;} else {res[key]=$0;}}
END {for(key in res){
print key;
print res[key];
}}
Если вы хотите sed
+фриллз, это, кажется, работает:
cat data.txt | sed -e '/^a/,/^[b-z]/!d' | sed -e '2,${ /^[a-z]/d }'
(Да, это бесполезное использование кота по дидактическим причинам, и. e. Я путаюсь, когда файл где-то посередине моих труб.)
Первый sed
рассматривает все диапазоны, которые начинаются со строки, начинающейся с a
, и заканчиваются строкой, начинающейся с буквы b-z
, включительно. Он отрицает этот диапазон (!
), а затем удаляет все совпадающее, поэтому мы остаемся с
a
1 2 3
1223
b
a
4 5
c
Второй sed
смотрит только на диапазон от строки 2 до конца файла (для сохранения заголовка a
), а внутри него удаляет все строки, которые начинаются с буквы a-z
, оставляя только числовые строки:
a
1 2 3
1223
4 5
Чтобы получить список всех ваших заголовков, я бы попробовал grep '^[a-z]". | сорт -u
. Так что все зверь:
for key in $(grep '^[a-z]' data.txt | sort -u ); do
cat data.txt | sed -e "/^$key/,/^[b-z]/\!d" | sed -e '2,${ /^[a-z]/d }' ;
done
awk '
/^[a-z]$/{
i=$0
next
}
{
A[i]=A[i] "\n" $0
}
END{
for (j in A)
print j A[j]
}'
Как вы можете видеть, упрощенный вариант @ulrich Schwarz Script : для линий, которые состоят только 1 нижняя буква, возьмите это письмо как индекс I
и начать новую линейную петлю. Далее поставьте все остаются линии (которые не состоят только 1 нижнюю букву », потому что он работал ранее) в ассоциативный массив A
согласно I
NDEX урегулирован из предыдущей части сценария с \ N
Разделитель EWLINE. Когда скрипт пропускает все линии (достичь END
), затем массив печати A
I
ndexes.