У меня есть текстовый файл с форматом word @@@ type @@@ sentence
в каждой строке, отсортированный по 'word' в порядке возрастания. Однако некоторые строки не являются уникальными и начинаются с того же слова, что и предыдущая строка, т.е. см. word1 ниже:
...
word0 @@@ type2 @@@ sentence0
word1 @@@ type1 @@@ sentence1
word1 @@@ type1 @@@ sentence2
word1 @@@ type1 @@@ sentence3
word1 @@@ type2 @@@ sentence4
word2 @@@ type1 @@@ sentence5
...
Я хочу объединить строки, содержащие одинаковые комбинации слов и типов, в одну, добавив предложения, чтобы файл получился следующим:
...
word0 @@@ type2 @@@ sentence0
word1 @@@ type1 @@@ sentence1 ;;; sentence2 ;;; sentence3
word1 @@@ type2 @@@ sentence4
word2 @@@ type1 @@@ sentence5
...
Поля слова и типа не содержат пробелов.
решение1
Предположим, что ваши входные данные отсортированы по обоим полям word
и type
, как это видно из опубликованного вами примера входных данных:
$ cat tst.awk
BEGIN { FS=" @@@ "; ORS="" }
{ curr = $1 FS $2 }
curr != prev {
printf "%s%s", ORS, $0
prev = curr
ORS = RS
next
}
{ printf " ;;; %s", $NF }
END { print "" }
$ awk -f tst.awk file
word0 @@@ type2 @@@ sentence0
word1 @@@ type1 @@@ sentence1 ;;; sentence2 ;;; sentence3
word1 @@@ type2 @@@ sentence4
word2 @@@ type1 @@@ sentence5
Вышеприведенный код будет работать с любым awk в любой оболочке на любой машине UNIX, будет хранить в памяти только одну строку за раз и будет выводить данные в том же порядке, что и ввод.
решение2
Вот один из способов на awk:
$ awk -F'@@@' '{ $1 in a ? a[$1][$2]=a[$1][$2]" ;;; "$3 : a[$1][$2]=$3}END{for(word in a){for (type in a[word]){print word,FS,type,FS,a[word][type]} }}' file
word0 @@@ type2 @@@ sentence0
word1 @@@ type1 @@@ sentence1 ;;; sentence2 ;;; sentence3
word1 @@@ type2 @@@ ;;; sentence4
word2 @@@ type1 @@@ sentence5
Или, немного более разборчиво:
awk -F'@@@' '{
if($1 in a){
a[$1][$2]=a[$1][$2]" ;;; "$3
}
else{
a[$1][$2]=$3
}
}
END{
for(word in a){
for (type in a[word]){
print word,FS,type,FS,a[word][type]
}
}
}' file
Обратите внимание, что для этого требуется awk
реализация, которая понимает многомерные массивы, например GNU awk ( gawk
), которая используется по умолчанию awk
в системах Linux.