2015-04-23 3 views
1

у меня есть файл такого рода:сохранить некоторые строки файла в соответствии с некоторыми условиями

K1 bla STARTED 
K1 bla FINISHED 
K2 blu FINISHED 
K3 bli STARTED 
K3 bli DIED_SKIPPED_PERMANENTLY 
K4 blo STARTED 
K5 ble STARTED 
K5 ble DIED_SKIPPED_PERMANENTLY 
K6 blou STARTED 
K6 blou STARTED 

От этого я хочу, чтобы получить файл, где, когда для каждого имени в колонке 1 есть FINISHED или DIED_SKIPPED_PERMANENTLY, только строка, содержащая эту информацию, присутствует, а не другие (с ЗАПУСКОМ или другими вещами). Кроме того, если две строки идентичны (например, одна из K6), я хочу напечатать только одну.

С моим примером, результат будет:

K1 bla FINISHED 
K2 blu FINISHED 
K3 bli DIED_SKIPPED_PERMANENTLY 
K4 blo STARTED 
K5 ble DIED_SKIPPED_PERMANENTLY 
K6 blou STARTED 

Я не могу удалить только с помощью

grep -v STARTED 

, потому что для некоторых имен, как К4 в моем примере, только эта строка присутствует и я хочу знать, что это началось (или нет), поэтому мне нужно сохранить эту информацию.

У меня есть файл со всеми именами из столбца 1, что я получил с:

awk '{print $1}' file | sort | uniq > names # 7,752 lines 

Я думал о петле такого рода:

Для каждого имен, присутствующих в файле «имена », сделайте следующее:

Если один из линии с $ line содержит FINISHED или DIED_SKIPPED_PERMANENTLY, а затем распечатать только ту строку в моем выходе и не печатает другие. Ищите все строки, содержащие это имя. Но удалите строки, которые идентичны.

Вот эта идея, но я не знаю, как я могу это сделать. я был бы признателен, если кто-то может помочь

+3

'только строка, содержащая эту информацию, присутствует, а не другие (с ЗАПУСКОМ или другими вещами)', но на вашем выходе есть «НАЧАЛО»? что вы имеете в виду? – Kent

ответ

0

Использование AWK и массивы

awk '!a[$1]||/DIED_SKIPPED_PERMANENTLY|FINISHED/{a[$1]=$0}END{for(i in a)print a[i]}' f 

Выход

K1 bla FINISHED 
K2 blu FINISHED 
K3 bli DIED_SKIPPED_PERMANENTLY 
K4 blo STARTED 
K5 ble DIED_SKIPPED_PERMANENTLY 
K6 blou STARTED 

Примечание это, чтобы получить ожидаемый результат вы выложили, но не будет работать для фактическое описание.

1

Мы можем использовать тот факт, что STARTED лексикографический больше, чем как FINISHED и DIED_SKIPPED_PERMANENTLY и использовать

sort filename | awk '!seen[$1,$2]++' 

Поскольку STARTED лексикографический наибольшими, STARTED линии всегда будет появляться после FINISHED или DIED_SKIPPED_PERMANENTLY линии, когда sort делаются , Код awk проходит через отсортированные строки и печатает только те, где он не видел комбинацию полей 1 и 2 раньше.

+0

Это прекрасно работает, спасибо большое !!! – user236152

0
awk '$3 ~ /FINISHED|DIED_SKIPPED_PERMANENTLY/ && !a[$0]++' input 

Это просто проверяет, если третий столбец соответствует либо FINISHED или DIED_SKIPPED_PERMANENTLY и сохраняет полную строку в массиве a, печатая это только первый раз, когда он видел. Обратите внимание, что это будет печатать строки, содержащие «FOO_FINISHED» третий столбец, но это не должно быть проблемой.Однако, учитывая при условии, пример вывода, я думаю, что вы на самом деле ищете:

awk '$1!=p && NR>1{print l}; {p=$1;l=$0}END{ if($1!=p)print l}' input 

который печатает последнюю строку, в которой данное поле возникает в колонке 1, когда ключи в колонке 1 появляется смежно.

+0

Это не печатает начатые строки, также есть паразитный '/' в конце –

+0

Нет, он не печатает строки, соответствующие «НАЧАЛО». Он соответствует описанию, данному в вопросе, а не предоставленному выводу, что является непоследовательным. –

+0

О да, мой/ОП плохо! –

Смежные вопросы