awk-разделить только по первому вхождению

я сказала:

one:two:three:four:five:six seven:eight

и я хочу использовать awk и один на two:three:four:five:six seven:eight

Я знаю, что могу получить его, делая sed раньше. То есть изменить первое вхождение : С sed затем awk он использует новый разделитель.

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

я хочу знать, есть ли возможность получить awk вести себя так

что-то вроде:

awk -F: '{print ,}'

выведет:

one two:three:four:five:six seven:eight

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

3 ответов


без каких-либо замен

echo "one:two:three:four:five" | awk -F: '{ st = index(,":");print  "  " substr(,st+1)}'

команда index находит первое появление": "во всей строке, поэтому в этом случае переменная st будет установлена в 4. Затем я использую функцию substr, чтобы захватить всю остальную строку, начиная с позиции st+1, если конечный номер не указан, он перейдет в конец строки. Выход

one  two:three:four:five

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

rem = substr(,st+1)

обратите внимание, что это было протестировано на Solaris AWK, но я не вижу причин, почему это не должно работать на других вкусах.


ближе всего вы можете получить с помощью GNU awk's FPAT:

$ awk '{print }' FPAT='(^[^:]+)|(:.*)' file
one

$ awk '{print }' FPAT='(^[^:]+)|(:.*)' file
:two:three:four:five:six seven:eight

но будет включать ведущий разделитель, но вы можете использовать substr исправить это:

$ awk '{print substr(,2)}' FPAT='(^[^:]+)|(:.*)' file
two:three:four:five:six seven:eight

так что все вместе:

$ awk '{print , substr(,2)}' FPAT='(^[^:]+)|(:.*)' file
one two:three:four:five:six seven:eight

сохранение результатов substr обратно в позволит дальнейшую обработку на без ведущего разделителя:

$ awk '{=substr(,2); print ,}' FPAT='(^[^:]+)|(:.*)' file
one two:three:four:five:six seven:eight

решение, которое должно работать с mawk 1.3.3:

awk '{n=index(,":");s=;=substr(s,1,n-1);=substr(s,n+1);print }' FS=''
one

awk '{n=index(,":");s=;=substr(s,1,n-1);=substr(s,n+1);print }' FS=''
two:three:four five:six:seven

awk '{n=index(,":");s=;=substr(s,1,n-1);=substr(s,n+1);print ,}' FS=''
one two:three:four five:six:seven

какой такой?

echo "one:two:three:four:five:six" | awk '{sub(/:/," ")}1' 
one two:three:four:five:six

это заменяет первый : в пространстве. Вы можете потом получить его в $1, $2

echo "one:two:three:four:five:six" | awk '{sub(/:/," ")}1' | awk '{print ,}'
one two:three:four:five:six

или в том же awk, поэтому даже с заменой вы получаете $1 и $2 так, как вам нравится

echo "one:two:three:four:five:six" | awk '{sub(/:/," ");=;print ,}'
one two:three:four:five:six

изменить: Используя другой разделитель, вы можете получить first one подана и остальные в такой:

echo "one:two:three:four:five:six seven:eight" | awk -F\| '{sub(/:/,"|");=;print "=" "\n="}'
=one
=two:three:four:five:six seven:eight

уникальный разделитель

echo "one:two:three:four:five:six seven:eight" | awk -F"#;#." '{sub(/:/,"#;#.");=;print "=" "\n="}'
=one
=two:three:four:five:six seven:eight