#awk
#awk
Вопрос:
В настоящее время я использую скрипт awk, который сравнивает числа в непоследовательном порядке и выводит разницу. Это довольно хорошо работает для чисел, но если у меня есть буквенно-цифровые символы, это, похоже, работает не очень хорошо
В своем текущем состоянии, помимо простого сравнения чисел, он дополнительно выполняет две вещи :
-
В настоящее время он учитывает нули перед числом или символом и сравнивает только абсолютные значения, игнорируя нули перед числом или символом
-
В настоящее время, если одно и то же число или символ встречается несколько раз в обоих файлах, это выводит дополнительное событие
я просто хочу, чтобы скрипт хорошо работал с буквенно-цифровыми символами, так как в настоящее время он, похоже, хорошо работает только с простыми числами. Может кто-нибудь, пожалуйста, отредактировать скрипт, чтобы получить желаемый результат, также учитывая вышеуказанные 2 условия
Текущий скрипт
awk '{k=$0 0}
NR==FNR {a[k] ; next}
!(k in a amp;amp; a[k]-->0);
END {for(k in a) while(a[k]-->0) print k}' file1 file2
Пример ниже
файл cat1
1
01
001
8
2B
12
13C
027B
0027B
cat file2
1
2
08
12
13C
02B
9
27B
Ожидаемый результат
1
1
2
9
27B
Объяснение ожидаемого результата
In file1 : "1" , "01" , "001" evaluates to 1 * 3 times
In file 2 : "1" is present only once
Hence "1" is present twice in result ( 3-1 times )
"2" and "9" are exclusively present in file2 , So obviously both simply form part of output
In file1 : '027B" , "0027B" evaluates to 27B * 2 times
In file 2 - "27B" is present only once
Hence '27B" is present once in result ( 2 -1 times )
Объяснение совпадающих элементов (которые не являются частью ожидаемого результата)
"8" from file1 ( line 4 )is matched with "08" from file2 ( line 3)
"12" from file1 ( line 6) is matched with "12" from file2 ( line 4)
"13C" from file1 (line 7 ) is matched with "13C" from file2 ( line 5 )
"2B" from file1 ( line 5 ) is matched with "02B" from file2 ( line 6 )
Наконец, порядок элементов в ожидаемом выводе должен быть в порядке возрастания, как показано в моем примере выше, допустим, если в приведенном выше примере ожидаемый вывод имел 3, он должен читаться по вертикали как 1 1 2 3 9 27B
Комментарии:
1. Это непонятно, не могли бы вы, пожалуйста, пояснить, почему
8
и13c
не входит в ожидаемый результат вашего?2. У File1 есть «8» в 4-й строке, а у file2 было «08» в 3-й строке, абсолютное значение совпадает. «13C» присутствует в file1 в 3-й последней строке и 5-й строке в file2, поэтому его совпадение, следовательно, оба не являются частью ожидаемого результата
3. В файле 1 — 1, 01,001 вычисляется 1 * 3 раза, 1 присутствует в file2 один раз, поэтому он является частью выходных данных дважды (3-1 раз). 2 и 9 присутствуют исключительно в file2 . 0027B, а 027B оценивается как 27B, присутствующий дважды в файле 1 и один раз в file2, поэтому образует часть выходных данных один раз (2-1 раз). Я также предоставил объяснение для других выходных элементов.
4. Не могли бы вы, пожалуйста, проверить один раз
paste <(awk '{sub(/^0 /,"")} 1' file1) <(awk '{sub(/^0 /,"")} 1' file2) | awk '$1==$2'
и сообщить мне, если это то, что вы ищете? Я все еще не понял ваш вопрос.5. @RavinderSingh13 получил эту ошибку — zsh: ошибка синтаксического анализа рядом с `)’
Ответ №1:
Этого должно быть достаточно, чтобы удалить начальные нули при формировании ключа (с особым случаем для нулевых значений, таких как 0000
):
/^0 $/ { k = 0 }
/[^0]/ { k = $0; sub(/^0*/, "", k) }
NR==FNR {a[k] ; next}
!(k in a amp;amp; a[k]-->0);
END {for(k in a) while(a[k]-->0) print k}
$ awk -f a.awk file1 file2
2
9
27B
1
1
ОТРЕДАКТИРУЙТЕ
Если вы просто хотите, чтобы значения были отсортированы численно, перейдите в раздел сортировка:
$ awk -f a.awk file1 file2 | sort -n
1
1
2
3
4
5
9
27B
Для вывода в порядке, указанном в file2, вы можете запомнить порядок в другом массиве, а затем выполнить всю печать в КОНЕЧНОМ блоке. Эта версия будет выводить значения в порядке file2, причем любые значения только в file1 будут напечатаны последними.
/^0 $/ { k = 0 }
/[^0]/ { k = $0; sub(/^0*/, "", k) }
NR==FNR {a[k] ; next}
{ b[FNR] = k }
!(k in a amp;amp; a[k]--) { a[k] = 1 }
END {
for (i=1; i<=FNR; i) {
k = b[i]
while(a[k]-->0) print k
}
for (k in a) {
while(a[k]-->0) print k
}
}
$ awk -f a.awk file1 file2
1
1
2
9
27B
3
4
5
Комментарии:
1. Похоже, что этот скрипт не работает, если перед буквенно-цифровым символом присутствует ноль.. Первый момент в моем вопросе — он должен сравнивать только абсолютное значение числа, и это должно быть сохранено. Я только что добавил 02B в рассматриваемый файл 2, и теперь он не функционирует должным образом, выводит как 2B, так и 02B. он должен рассматривать 02B как совпадающий с 2B, как будто он соответствует 02 с 2
2. Смотрите обновленную версию, которая работает для таких случаев, как
2B
/02B
3. спасибо, кажется, теперь это работает, наконец, возможно ли отсортировать результат в порядке возрастания, аналогичном ожидаемому результату моего вопроса
4. Обновите версией, которая выводится в соответствии с порядком в file2
5. Хорошо, надеюсь, на этот раз я все понял 🙂 Попробуйте «повторно отредактировать» и давайте посмотрим.