Как классифицировать эти строки в этом ASCII-файле

Вы можете взглянуть на то, насколько 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% надежный способ получить эту информацию.

0
10.03.2015, 23:34
4 ответа

Вот решение 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. Это разделяет хиты каждого запроса. Я структурировал этот ответ так, чтобы вы могли сделать запрос на каждую букву, что в моем понимании этого вопроса)

.
1
28.01.2020, 02:14

Ах, 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
2
28.01.2020, 02:14
awk '/^[a-z]$/ { f = $1=="a" ; if (!c++) print ; next }; f'
2
28.01.2020, 02:14
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.

2
28.01.2020, 02:14

Теги

Похожие вопросы