Как сохранить формат файла, если вы используете команду uniq (в оболочке)? - PullRequest
6 голосов
/ 13 марта 2009

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

Но в имеющемся у меня файле порядок информации важен, поэтому как мне сохранить исходный формат файла, но при этом избавиться от дублированного содержимого?

Ответы [ 7 ]

10 голосов
/ 13 марта 2009

Другая версия awk:

awk '!_[$0]++' infile
4 голосов
/ 13 марта 2009

Существует также метод "номер строки, двойная сортировка".

 nl -n ln | sort -u -k 2| sort -k 1n | cut -f 2-
4 голосов
/ 13 марта 2009

Это awk сохраняет первое вхождение. Тот же алгоритм, что и в других ответах:

awk '!($0 in lines) { print $0; lines[$0]; }'

Вот тот, который должен хранить только дублированные строки (в отличие от всех строк), используя awk:

sort file | uniq -d | awk '
   FNR == NR { dups[$0] }
   FNR != NR && (!($0 in dups) || !lines[$0]++)
' - file
1 голос
/ 13 марта 2009

Использование только uniq и grep:

Создать d.sh:

#!/bin/sh
sort $1 | uniq > $1_uniq
for line in $(cat $1); do
cat $1_uniq | grep -m1 $line >> $1_out
cat $1_uniq | grep -v $line > $1_uniq2
mv $1_uniq2 $1_uniq
done;
rm $1_uniq

Пример:

./d.sh infile
1 голос
/ 13 марта 2009

Вы можете запустить uniq -d для отсортированной версии файла, чтобы найти дубликаты строк, а затем запустить какой-нибудь скрипт, который говорит:

if this_line is in duplicate_lines {
    if not i_have_seen[this_line] {
        output this_line
        i_have_seen[this_line] = true
    }
} else {
    output this_line
}
0 голосов
/ 13 марта 2009
for line in $(sort file1 | uniq ); do
    grep -n -m1 line file >>out
done;

sort -n out

сначала сделайте сортировку,

для каждого уникального значения grep для первого совпадения (-m1)

и сохранить номера строк

отсортировать вывод численно (-n) по номеру строки.

вы можете удалить строки # с помощью sed или awk

0 голосов
/ 13 марта 2009

Вы можете использовать что-то ужасное O (n ^ 2), например так (псевдокод):

file2 = EMPTY_FILE
for each line in file1:
  if not line in file2:
    file2.append(line)

Это потенциально довольно медленно, особенно если реализовано на уровне Bash. Но если ваши файлы достаточно короткие, они, вероятно, будут работать очень хорошо и будут быстро реализованы (not line in file2 - это просто grep -v и т. Д.).

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

...