Есть массив данных:
https://example.com:description of the site/application:category
http://example.com:description of the site/application:category
android://package name:description of the site/application:category
android://package name|description of the site/application|category
Я хочу разделить данные на 3 столбца:
Насколько я понимаю, необходимо добавить регулярное выражение для игнорирования первого ":" а также 2 аргумента для делителя "|"
Я попробовал это выражение, но вывод неверен
cat * | awk -F["|"][:] '{print $1,$2, $3}'
А если есть URL, он всегда в начале строки?
Пожалуйста, отредактируйте , чтобы обеспечить входные и ожидаемые выходные данные в виде чистого текста (поместите ```none
на строку над текстом примера и ```
под ним). См. также справочный центр и, в частности, Как спрашивать , а также руководство по предоставлению минимально воспроизводимого примера.
Желаемый результат содержит четыре элемента, тогда как вы говорите, что это должно быть три столбца.
Могут ли description of the site/application
или category
содержать :
или |
? Может ли URL-адрес содержать дополнительные :
или |
? Пожалуйста, используйте в примерах действительно репрезентативные значения, а не просто одни и те же общие строки, повторяющиеся в каждой строке, чтобы мы могли лучше вам помочь.
С помощью GNU sed: sed 's/[:|]/\t/2g' file
Вы можете заметить, что при разделении с помощью [:|]
у вас есть 4 поля в строке:
awk -F '[:|]' '{ print NF }' infile
Выход:
4
4
4
4
Итак, предполагая, что все ваши строки отформатированы таким образом, вы можете получить 3 столбца, объединив поля 1 и 2, например:
awk -F '[:|]' -v OFS='\t' '{ print $1":"$2, $3, $4 }' infile
Выход:
https://example.com description of the site/application category
http://example.com description of the site/application category
android://package name description of the site/application category
android://package name description of the site/application category
вам также может потребоваться указать http://host:port/path
или http://host/path1:path2
@jhnc: Не согласно примерам ОП
правда, но ответ должен помочь любому
Также обратите внимание, что вы можете избежать бесполезного использования кота с помощью awk '...' *
@jhnc, возможно, описание и/или категория могут содержать :
, и тогда любое решение, которое пытается разместить несколько :
в URL-адресе, будет неверным.
@EdMorton, если они могут появиться где угодно, то, конечно же, строку невозможно разобрать без дополнительных правил?
@jhnc. Да, это правильно. До тех пор, пока ОП не предоставит более репрезентативную выборку входных/выходных данных, мы все просто догадываемся, что на самом деле может быть в их входных данных. Я сильно подозреваю, что URL-адрес на самом деле не содержит пробелов, и реальным решением будет использование не-пробелов до последнего :
перед первым «словом» описания в качестве URL-адреса, а последнее :
до последнего. конец строки — «категория», а строка между ними — «описание», но мы посмотрим, что в конечном итоге нам скажет и покажет ОП в примере.
@EdMorton, возможно, забавно, но в Linux :
может появиться в поле командного интерпретатора /etc/passwd
@jhnc Я только что обновил свой ответ, чтобы показать, как, по моему мнению, на самом деле будут выглядеть входные данные OP, и сценарий sed для работы с ним.
Если формат может быть одним из:
url:description:category
url|description|category
и только url
может содержать дополнительные :
или |
, а затем перейти на разделители табуляции с помощью sed
:
sed -E 's/(.*)([:|])(.*)\2(.*)/\1\t\3\t\4/' file
Первый .*
потребляет как можно больше, а значит, потребляет и любые излишки :
и |
.
Используя любой awk:
$ awk -F'[:|]' -v OFS='\t' '{sub(/:/,RS); sub(RS,":",$1)} 1' file
https://example.com description of the site/application category
http://example.com description of the site/application category
android://package name description of the site/application category
android://package name description of the site/application category
или, если символ OFS
не может присутствовать в URL-адресе при вводе:
$ awk -F'[:|]' -v OFS='\t' '{$1=$1; sub(OFS,":")} 1' file
https://example.com description of the site/application category
http://example.com description of the site/application category
android://package name description of the site/application category
android://package name description of the site/application category
Установите OFS
на что-то отличное от \t
по своему усмотрению.
Пожалуйста, прочитайте спецификацию POSIX, чтобы узнать, что означают выражения в скобках, такие как те, которые вы использовали, ["|"][:]
, и те, которые я использовал, [:|]
.
Сказав это, я подозреваю, что реальный ввод OP, вероятно, выглядит примерно так (где в URL-адресе и/или описании могут появляться дополнительные :
или |
, но в URL-адресе не может быть буквальных пробелов):
$ cat file
https://example.com:description of : the site/application:category
http://example.com:description: of the site/application:category
android://package%20name:description of the site/application:category
android://package%20name|description of the site/application|category
android://package_name:17:something:description of the :huge: site/application:category
а затем вы можете получить желаемый результат, используя следующий скрипт sed
(используя sed, который имеет -E
для включения ERE, например, sed GNU и BSD):
$ sed -E 's/([^ ]+)[:|]([^ ].*)[:|]/\1\t\2\t/' file
https://example.com description of : the site/application category
http://example.com description: of the site/application category
android://package%20name description of the site/application category
android://package%20name description of the site/application category
android://package_name:17:something description of the :huge: site/application category
или используя любой sed:
$ sed 's/\([^ ]*\)[:|]\([^ ].*\)[:|]/\1\t\2\t/' file
https://example.com description of : the site/application category
http://example.com description: of the site/application category
android://package%20name description of the site/application category
android://package%20name description of the site/application category
android://package_name:17:something description of the :huge: site/application category
Эти команды sed предполагают, что описание содержит как минимум 1 пробел и не начинается с :
или word:word
— если это не так, то невозможно отделить описание от URL-адреса, учитывая то, что мы знаем о вводе.
@jhnc так и есть, хорошо! Я вижу, что nextfile
добрался до awk
и сейчас. У меня была куча заявок от ребят из POSIX, которые были приняты, и поэтому я надеялся, что тоже справлюсь (например, определение значения $0
в разделе END
, определение того, что NF++
делает, определение того, что делает разбиение по нулевому FS
, и т. д.), но, похоже, я открыл их слишком поздно. Эх, в следующий раз...
где могут появиться
:
и|
, если они не являются разделителями? только в URL?