Как работает эта команда awk?

Есть ли причина, по которой вы используете исключительно awk? Чтобы решить вашу проблему, вам нужно сначала разделить данные на каждую единицу, отсортировать, удалить дубликаты, а затем воссоединиться. Хотя вы можете сделать это с помощью любого подходящего языка программирования или сценариев (, даже C ), действительно ли стоит изобретать велосипед, когда уже есть инструменты, способные делать то, что вам нужно?

Если опубликованные вами данные являются реальным представлением данных, с которыми вы работаете, вы можете быстро обработать их с помощью следующих команд:

$ cat RAW_DATA
<ITEM ID='81'>,< 1>KWIKSET</1>,< 2>PASS</2>,< 7>KNOB</7>,< 5a>RIGHT</5a>,< 8c>BRASS</8c>,< 2>TYLO</2>,< 2>PASS</2>,< 5a>RIGHT</5a>,< 8c>BRASS</8c>
<ITEM ID='82'>,< 1>KWIKSET</1>,< 4a>PRIVACY</4a>,< 7>KNOB</7>,< 8b>SATIN</8b>,< 8c>CHROME</8c>,< 2>TYLO</2>,< 4a>PRIVACY</4a>,< 8b>SATIN</8b>,< 8c>CHROME</8c>
<ITEM ID='83'>,< 1>KWIKSET</1>,< 8b>POLISHED</8b>,< 8c>BRASS</8c>
$ while read line; do echo "$(cut -d, -f1 <<< "$line"),$(cut -d, -f2- <<< "$line" | tr ',' '\n' | sort -n | uniq | paste -sd,)"; done < RAW_DATA
<ITEM ID='81'>,< 1>KWIKSET</1>,< 2>PASS</2>,< 2>TYLO</2>,< 5a>RIGHT</5a>,< 7>KNOB</7>,< 8c>BRASS</8c>
<ITEM ID='82'>,< 1>KWIKSET</1>,< 2>TYLO</2>,< 4a>PRIVACY</4a>,< 7>KNOB</7>,< 8b>SATIN</8b>,< 8c>CHROME</8c>
<ITEM ID='83'>,< 1>KWIKSET</1>,< 8b>POLISHED</8b>,< 8c>BRASS</8c>

Цикл whileсчитывает каждую строку файла и обрабатывает ее отдельно. Затем мы хотим отобразить новую строку, где cut -d, -f1 <<< "$line"извлекает только первое поле, поскольку оно статично, а cut -d, -f2- <<< "$line" | tr ',' '\n' | sort -n | uniq | paste -sd,извлекает оставшиеся поля, сортирует их в числовом виде, фильтрует уникальные значения и использует paste -sd,для воссоединения в виде запятой -список с разделителями.

1
04.02.2021, 13:53
1 ответ

вы (разделили )команда awk выглядит так

awk '(NR>1) {print "s/"p"/"$1"/g"}
            {p=$1}'

что означает

  • сделать {print "s/"p"/"$1"/g"}когдаNR>1
  • делать {p=$1}всегда
  • "s/"p"/"$1"/g"кавычки разбиваются (1 ):"s/" + p + "/" + $1 + "/g", ни p, ни $1не цитируются
  • (1)+для конкатенации, обратите внимание, что awk использует пробел (без пробела )как неявный оператор конкатенации

в первой строке выполняется только {p=$1}.

во второй строке {print "s/"p"/"$1"/g"}выполняется первым, и значение pинициализируется из первой строки.

в последней строке, pзаканчиваются pfg039G, которые отбрасываются.


Используйте точку с запятой в том же кодовом блоке, чтобы создать последовательность команд:

awk '(NR>1) {print "s/"p"/"$1"/g" ; p=$1}' test.txt
s//pfg025T/g
s/pfg025T/pfg034T/g
s/pfg034T/pfg039G/g

Теперь результат, как и ожидалось, с использованием $1из предыдущего совпадения -в первой строке, $1пусто.

3
18.03.2021, 22:32

Теги

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