Объедините данные с несколькими разными разделителями

Есть массив данных:

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 столбца:

URL-адрес Описание Категория https://example.com описание сайта/приложения категория http://example.com описание сайта/приложения категория Android://имя пакета описание сайта/приложения категория Android://имя пакета описание сайта/приложения категория

Насколько я понимаю, необходимо добавить регулярное выражение для игнорирования первого ":" а также 2 аргумента для делителя "|"

Я попробовал это выражение, но вывод неверен

cat * | awk -F["|"][:] '{print $1,$2, $3}'

где могут появиться : и |, если они не являются разделителями? только в URL?

jhnc 11.08.2024 11:48

А если есть URL, он всегда в начале строки?

The fourth bird 11.08.2024 11:51

Пожалуйста, отредактируйте , чтобы обеспечить входные и ожидаемые выходные данные в виде чистого текста (поместите ```none на строку над текстом примера и ``` под ним). См. также справочный центр и, в частности, Как спрашивать , а также руководство по предоставлению минимально воспроизводимого примера.

tripleee 11.08.2024 11:54

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

tripleee 11.08.2024 11:56

Могут ли description of the site/application или category содержать : или |? Может ли URL-адрес содержать дополнительные : или |? Пожалуйста, используйте в примерах действительно репрезентативные значения, а не просто одни и те же общие строки, повторяющиеся в каждой строке, чтобы мы могли лучше вам помочь.

Ed Morton 11.08.2024 14:15

С помощью GNU sed: sed 's/[:|]/\t/2g' file

Cyrus 11.08.2024 15:38
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
79
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете заметить, что при разделении с помощью [:|] у вас есть 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 11.08.2024 13:43

@jhnc: Не согласно примерам ОП

Thor 11.08.2024 13:44

правда, но ответ должен помочь любому

jhnc 11.08.2024 13:45

Также обратите внимание, что вы можете избежать бесполезного использования кота с помощью awk '...' *

tripleee 11.08.2024 13:51

@jhnc, возможно, описание и/или категория могут содержать :, и тогда любое решение, которое пытается разместить несколько : в URL-адресе, будет неверным.

Ed Morton 11.08.2024 14:13

@EdMorton, если они могут появиться где угодно, то, конечно же, строку невозможно разобрать без дополнительных правил?

jhnc 11.08.2024 14:16

@jhnc. Да, это правильно. До тех пор, пока ОП не предоставит более репрезентативную выборку входных/выходных данных, мы все просто догадываемся, что на самом деле может быть в их входных данных. Я сильно подозреваю, что URL-адрес на самом деле не содержит пробелов, и реальным решением будет использование не-пробелов до последнего : перед первым «словом» описания в качестве URL-адреса, а последнее : до последнего. конец строки — «категория», а строка между ними — «описание», но мы посмотрим, что в конечном итоге нам скажет и покажет ОП в примере.

Ed Morton 11.08.2024 14:22

@EdMorton, возможно, забавно, но в Linux : может появиться в поле командного интерпретатора /etc/passwd

jhnc 11.08.2024 14:22

@jhnc Я только что обновил свой ответ, чтобы показать, как, по моему мнению, на самом деле будут выглядеть входные данные OP, и сценарий sed для работы с ним.

Ed Morton 11.08.2024 14:28

Если формат может быть одним из:

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-адреса, учитывая то, что мы знаем о вводе.

-E превратился в стандарт!
jhnc 11.08.2024 15:55

@jhnc так и есть, хорошо! Я вижу, что nextfile добрался до awk и сейчас. У меня была куча заявок от ребят из POSIX, которые были приняты, и поэтому я надеялся, что тоже справлюсь (например, определение значения $0 в разделе END, определение того, что NF++ делает, определение того, что делает разбиение по нулевому FS, и т. д.), но, похоже, я открыл их слишком поздно. Эх, в следующий раз...

Ed Morton 11.08.2024 16:51

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