Числовые оси согласно их содержанию

Этот отрывок оболочки генерирует IP-адрес.

ip_address=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null |
             od -An -tu1 |
             sed -e 's/^ *//' -e 's/  */./g')

Если Вы не довольны им, попробовали еще раз в цикле.

while
  set $(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -An -tu1)
  [ $1 -lt 224 ] &&
  [ $1 -ne 10 ] &&
  { [ $1 -ne 192 ] || [ $2 -ne 168 ]; } &&
  { [ $1 -ne 172 ] || [ $2 -lt 16 ] || [ $2 -gt 31 ]; }
do :; done
ip_address=$1.$2.$3.$4
1
17.05.2013, 14:46
4 ответа

Еще более простой с awk:-

awk '{ print ++c[$0],$0 }' < test

Где тест является файлом, который содержит данные. Я сделал несколько предположений здесь, которые не ясны из вопроса. Во-первых, я предполагаю, что файл уже отсортирован. В противном случае затем:-

sort < test | awk '{ print ++c[$0],$0 }'

Кроме того, я предполагаю, что целая строка является значительной, и не только первое слово, если должен быть больше чем один. Если Вы просто хотите работать над первым словом затем:-

awk '{ print ++c[$1],$0 }' < test

4
27.01.2020, 23:17
  • 1
    Но, если asdf происходит снова, это продолжит нумеровать, я понимаю это правильно? Но это было также не ясно из вопроса. Мне нравится Ваш подход. –  Bernhard 05.09.2012, 18:18
  • 2
    Да, корректный. Это было то, почему я спросил о сортировке, с тех пор как Вы говорите, вопрос не очень ясен. –  JohnCC 05.09.2012, 18:20

Можно выполнить итерации по входу и использовать счетчик

#!/bin/sh                                                                                                                                                     

counter=1
old=""

while IFS= read -r line ; do
    # check if the line is different from the previous one
    if [ "$line" != "$old" ] ; then
        counter=1
    fi
    old="$line"
    printf '%s\t%s\n' "$counter" "$line"
    counter=$((counter+1))
done

Можно запустить скрипт с:

$ sh scriptname.sh < inputfile
0
27.01.2020, 23:17
  • 1
    Спасибо, как я запускаю это от файла с разделением табуляцией? –  martijn 05.09.2012, 17:57
  • 2
    Отредактированный с вкладкой разграничил вывод –  Matteo 05.09.2012, 18:21
  • 3
    @Gilles, спасибо за редактирование. Просто вопрос, почему printf лучше затем echo? –  Matteo 06.09.2012, 08:16
  • 4
    @Matteo С echo -e, если бы входная строка содержит обратную косую черту, она была бы интерпретирована как символ ESC. -r опция читать по той же причине, и IFS= должен сохранить ведущий и запаздывающий пробел, видеть, Почему while IFS= read используемый так часто, вместо IFS=; while read..? –  Gilles 'SO- stop being evil' 06.09.2012, 16:28

Вы могли сделать это с awk:

number.awk

BEGIN { OFS = "\t" }

last == $1 { cnt += 1}
last != $1 { cnt  = 1 }

{ print cnt, $1; last = $1 }

Выполненный как это:

awk -f number.awk infile
1
27.01.2020, 23:17

При необходимости в чем-то, что работает независимое от того, кластеризируется ли вход (т.е. все случаи X являющийся после друг другом), необходимо использовать некоторый счетчик на каждого отличающегося X. Вы можете, например, использовать следующее в качестве фильтра или с ommandline параметром, пишущий в stdout:

#!/usr/bin/env python
import sys, collections
c = collections.Counter()
for line in sys.stdin if len(sys.argv) == 1 else open(sys.argv[1]):
    c[line] += 1
    sys.stdout.write("%s\t%s" % (c[line], line))
0
27.01.2020, 23:17

Теги

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