Удалить дубликаты в каждой строке файла
Как я могу удалить дубликаты в каждой строке, например, здесь?
1 1 1 2 1 2 3
5 5 4 1 2 3 3
Я хотел бы получить этот вывод:
1 2 3 
5 4 1 2 3
Есть много строк (100 000), и в каждой строке я хочу уникальные значения. Perl может быть самым быстрым, но как я могу сделать это в Perl или Bash?
3 ответа
Вот вариант с использованием awk:
awk '{ while(++i<=NF) printf (!a[$i]++) ? $i FS : ""; i=split("",a); print ""}' infile > outfile
Редактировать Обновлено с комментариями:
- while (++i<=NF)- Инициализирует цикл while, предваряя "i", поскольку $0 - это полная строка в awk. - Таким образом, он начинается с $1 (первое поле). Переходит по линии до конца (меньше или равно "NF", которое встроено в awk для "Количество полей"). Разделителем полей по умолчанию является пробел, вы можете легко изменить разделитель по умолчанию. 
- printf (!a[$i]++) ? $i FS : ""- Это троичная операция. - Итак, если вход не находится в массиве - !a[$i]++, затем он печатает $i, если это так, он печатает "". (Вы можете удалить- !и повернуть вспять- $i FS : ""если тебе не нравится это так).
- i=split("",a)- Обычно это нулевое разделение. В этом случае он сбрасывает I для следующей строки. 
- print ""- заканчивает строку для вывода (не 100%, почему, на самом деле), в противном случае вы бы получили вывод: - 1 2 3 5 4 1 2 3вместо- 1 2 3- 5 4 1 2 3
Поскольку ruby поставляется с любым дистрибутивом Linux, о котором я знаю:
ruby -e 'STDIN.readlines.each { |l| l.split(" ").uniq.each { |e| print "#{e} " }; print "\n" }' < test
Вот, test это файл, который содержит элементы.
Чтобы объяснить, что делает эта команда - хотя Ruby почти читается слева направо:
- Прочитайте ввод (который исходит от < testчерез вашу раковину)
- Пройдите каждую строку ввода
- Разбить строку на основе одного пробела, разделяющего элементы, в массив (split(" "))
- Получить уникальные элементы из этого массива (по порядку)
- Для каждого уникального элемента выведите его, включая пробел (print "#{e} ")
- Напечатайте новую строку, как только мы закончим с уникальными элементами
Не чистый баш, но...
while read line; do
    printf "%s\n" $line | sort -u | tr '\n' ' '
    echo ''
done < file
Линии будут отсортированы как побочный продукт.