Сравните 2 цифры и скопируйте только аналогичную часть sed / grep / awk

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

Если вы щелкните правой кнопкой мыши значок «Файл» в панели запуска, вы можете выбрать файл определенного типа (например, «Документы», «Изображения», «Презентации» и т. Д.), А «Даш» будет вы увидите все недавно использованные файлы этого типа в вашей домашней папке.

Существует найденная линза, которая делает более глубокие поиски.

Вот отчет об ошибке.
1
задан 22 June 2015 в 23:16

4 ответа

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

perl -le '@A=split(//,$ARGV[0]);@B=split(//,$ARGV[1]); 
          for $i (0..$#A){$A[$i] eq $B[$i] ? push @S,$A[$i] : last} 
          print @S' "${a[0]}" "${a[1]}"
.1.3.6.1.4.1.759.

Это, однако, включает в себя трейлинг .. Ваш результат не работает (несмотря на то, что он одинаковый для обеих переменных), поэтому, если вы хотите его удалить, используйте вместо этого:

$ perl -le '@A=split(/\./,$ARGV[0]);@B=split(/\./,$ARGV[1]); 
            for $i (0..$#A){$A[$i] eq $B[$i] ? push @S,$A[$i] : last} 
            print join ".",@S' "${a[0]}" "${a[1]}"
.1.3.6.1.4.1.759

Объяснение

-le: добавьте новую строку для каждого вызова print и запустите сценарий, заданный -e. @A=split(//,$ARGV[0]): $ARGV[0] - первый аргумент, заданный в командной строке. Это разделит его, сделав каждый символ элементом в массиве @A. @B=split(//,$ARGV[1]);: то же, что и выше, но для второго аргумента и массива @B. for $i (0..$#A): цикл for. Это устанавливает значение $i в 0 и увеличивает его на единицу, пока не будет установлено значение количества элементов в массиве @A ($#A). Это простой способ итерации по всем элементам массива, поскольку $A[$i] будет $A[0], $A[1], ..., $A[$#A]. $A[$i] eq $B[$i] ? push @S,$A[$i] : last: это сокращенная запись в стиле C. Общий формат foo ? bar : baz и означает «если foo истинно, do bar, else do baz. Здесь мы проверяем, будет ли n th (или $i th в этом случае) Элемент array @A совпадает с соответствующим из массива @B. Если он есть, мы добавляем его в третий массив @S. Если это не так, мы выходим из цикла с помощью last. print @S: напечатать массив @S, разделяемые элементы.

Оба решения очень похожи, единственное отличие состоит в том, что @A=split(/\./,$ARGV[0]) разделится на ., удалив их из результирующего массива и print join ".", @S будут печатать все элементы @S с . между ними.

4
ответ дан 23 May 2018 в 19:36

Как я уже упоминал в комментариях к вопросу, я нашел несколько простое решение awk: объединить два числа для создания одной длинной строки, заменить все точки пробелом (чтобы разрешить использование пространства в качестве поля по умолчанию разделитель в awk) и перейдите в поле сравнения строк с файлом + половина.

Основная команда

printf ${a[1]}${a[2]} | awk '{gsub("\\."," "); half=NF/2}; { for ( x=1; x<=half; x++ ) { if ( $x==$(x + half) ) printf "."$x };}'

Я тестировал это с помощью gawk и mawk, работал в обоих.

Здесь вывод с первым примером (.1.3.6.1.4.1.232.13600256 и .1.3.6.1.4.1.232.13600276):

$ printf ${a[1]}${a[2]} | awk '{gsub("\\."," "); half=NF/2}; { for ( x=1; x<=half; x++ ) { if ( $x==$(x + half) ) printf "."$x };}'
.1.3.6.1.4.1.232

Базовая команда [!d2 ]

Если вы хотите одновременно сравнить несколько строк, объедините их вместе и разделите с помощью новой строки в printf, затем добавьте printf в конце команды awk следующим образом:

[ f8]

Выход:

$ printf "${a[1]}${a[2]}\n${a[3]}${a[4]}" | awk '{gsub("\\."," "); half=NF/2}; { for ( x=1; x<=half; x++ ) { if ( $x==$(x + half) ) printf "."$x }; printf "\n"}'
.1.3.6.1.4.1.232 # same for a[1] and a[2]
.1.3.6.1.4.1.759 # same for a[3] and a[4]

Ограничение вывода

Теперь комментарий kos надлежащим образом заметил, что OP хочет отображать только 7 номеров. Для этого вы можете добавить канал в команду cut -d'.' -f1-8. Например:

printf "${a[5]}${a[6]}" | mawk '{gsub("\\."," "); half=NF/2}; { for ( x=1; x<=half; x++ ) { if ( $x==$(x + half) ) printf "."$x }; printf "\n"}' | cut -d'.' -f1-8

Вот пример вывода из моего терминала:

$ a[5]=.1.3.6.1.4.1.232.13600256.885


$ a[6]=.1.3.6.1.4.1.232.13600256.885


$ printf "${a[5]}${a[6]}" | mawk '{gsub("\\."," "); half=NF/2}; { for ( x=1; x<=half; x++ ) { if ( $x==$(x + half) ) printf "."$x }; printf "\n"}' | cut -d'.' -f1-8
.1.3.6.1.4.1.232.13600256.885


 half) ) printf "."$x }; printf "\n"}' | cut -d'.' -f1-8                      <
.1.3.6.1.4.1.232

Ограничение вывода [!d16 ]

Опять же, все можно поместить в awk-скрипт

#!/usr/bin/awk -f

{
 gsub("\\."," "); 
 half=NF/2
}; 

{ 
 for ( x=1; x<=half; x++ ) { 
    if ( $x==$(x + half) ) printf "."$x 
  }; 
  printf "\n"
}

Пример прогона:

$ printf "${a[5]}${a[6]}" | num-comp.awk | cut -d'.' -f1-8                     
.1.3.6.1.4.1.232

Сравнение с первым не равным числом

Awk имеет очень полезную функцию substr(string,X,Y), которая позволяет разрезать или «обрезать» строку, начиная с первого символа (x) и заканчивая (Y). Поэтому, зная это, давайте возьмем два числа как два поля одной строки и пропустим их через цикл. Мы будем продолжать увеличивать длину подстроки (начало до конца), пока они не станут равными. Когда мы сталкиваемся с неравными подстроками, мы выходим и печатаем последнюю известную равную подстроку.

echo ".1.3.6.1.4.1.232.13600256\t.1.3.6.1.4.1.232.13600276" | awk 'BEGIN{i=1}{ while(substr($1,1,i)==substr($2,1,i)){var=substr($1,1,i);i++};} END{print var}'

Особая благодарность terdon за предложение использования функции substr, которую я ранее делал даже не существовало

3
ответ дан 23 May 2018 в 19:36

Использование awk (gawk):

awk -F. '{printf "%s","similar part is "} {for(i=1;i<=NF;i++) {first[i-1]=$i} getline; for(i=1;i<=NF;i++) {second[i-1]=$i} for(i=0;i<length(first);i++) {if(first[i] == second[i]) {result=result first[i]"."}} printf "%s",substr($result,0,length(result)-1)"\n"}' <<< "$a"$'\n'"$b"

Или более читаемо:

awk -F. '{
    printf "%s","similar part is "
  }
  {
    for(i=1;i<=NF;i++) {
      first[i-1]=$i
    }

    getline;

    for(i=1;i<=NF;i++) {
      second[i-1]=$i
    }

    for(i=0;i<length(first);i++) {
      if(first[i] == second[i]) {
        result=result first[i]"."
      }
    }
    printf "%s",substr($result,0,length(result)-1)"\n"
}'

Пример

[ f3]

UPDATE В комментариях OP хочет совместить только до первого несоответствия:

awk -F. '{printf "%s","similar part is "} {for(i=1;i<=NF;i++) {first[i-1]=$i} getline; for(i=1;i<=NF;i++) {second[i-1]=$i} for(i=0;i<length(first);i++) {if(first[i] == second[i]) {result=result first[i]"."} else {i=length(first)}} printf "%s",substr($result,0,length(result)-1)"\n"}' <<< "$a"$'\n'"$b"

Пример [!d8 ]

$ a=".1.3.6.1.4.1.232.13600256.2"
$ b=".1.3.6.1.4.1.232.13600276.2"
$ awk -F. '{printf "%s","similar part is "} {for(i=1;i<=NF;i++) {first[i-1]=$i} getline; for(i=1;i<=NF;i++) {second[i-1]=$i} for(i=0;i<length(first);i++) {if(first[i] == second[i]) {result=result first[i]"."} else {i=length(first)}} printf "%s",substr($result,0,length(result)-1)"\n"}' <<< "$a"$'\n'"$b"
similar part is .1.3.6.1.4.1.232

Протестировано с помощью GNU Awk 4.1.1, API: 1.1 (GNU MPFR 3.1.2-p11, GNU MP 6.0.0)

3
ответ дан 23 May 2018 в 19:36
  • 1
    Это дает мне ошибку awk: line 1: illegal reference to array first – SamFlynn 22 June 2015 в 14:54
  • 2
    Я закончил, пожалуйста, проверьте текущую версию;) – A.B. 22 June 2015 в 15:24

Вы можете определить небольшую функцию python, которая может выполнять задание:

#!/usr/bin/env python2
import itertools
def common_portion(a):
    first = a[0].split('.')
    second = a[1].split('.')
    result = []
    for (i, j) in itertools.izip(first, second):
        if i == j:
            result.append(i)
        else:
            break
    return 'Similar part is ' + '.'.join(result)
Нам нужно предоставить список, содержащий строки, которые мы хотим проверить, как входные данные в переменную функции first будет содержать части первого элемента входного списка, разделенного на . (a[0].split). Аналогично second будет содержать части второго элемента списка a. Затем мы выполняем итерацию по first и second и проверяем равенство каждого элемента с тем же индексированным эквивалентом, если они одинаковы, тогда один из них сохраняется в отдельном списке result. Всякий раз, когда мы сталкиваемся с первой разницей, мы вырвались из цикла. Наконец, мы напечатали наш желаемый результат, соединяя поля с . s ('.'.join(result))

Test:

print common_portion(['.1.3.6.1.4.1.232.13600256', '.1.3.6.1.4.1.232.13600276'])

Similar part is .1.3.6.1.4.1.232


print common_portion(['.1.3.6.1.4.1.759.2344.454545', '.1.3.6.1.4.1.759.3234.454545'])

Similar part is .1.3.6.1.4.1.759
1
ответ дан 23 May 2018 в 19:36

Другие вопросы по тегам:

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