Как получить определенную строку с помощью команды sed

У меня есть входная строка, как показано ниже:

   VAL:1|b:2|c:3|VAL:<har:[email protected]>; tag=vy6r5BpcvQ|VAl:1234|name:mnp|VAL:91987654321

Таким образом, имеется более 1000 строк.

Я хочу получить значение первого параметра, то есть поля a и поля d, но для поля d я хочу только har:[email protected].

Я пробовал так:

cat $filename | grep -v Orig |sed -e 's/['a:','d:']//g' |awk -F'|' -v OFS=',' '{print $1 "," $4}' >> $NGW_DATA_FILE

Результат, который я получил, ниже:

1,<[email protected]>; tag=vy6r5BpcvQ

Я хочу, чтобы это было так,

1,har:[email protected]

Где я допустил ошибку и как ее решить?

Если вы все равно используете Awk, выполняйте всю эту обработку в Awk.

tripleee 11.12.2020 08:41

иногда я могу получить значение в том же имени поля, что и val: вместо a и d, тогда как я могу получить его значения

mark 11.12.2020 08:44
Стоит ли изучать 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
2
147
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Обновлено: в соответствии с изменением OP в Input_file и комментариями OP, теперь добавлено следующее.

awk '
BEGIN{ FS = "|"; OFS = "," }
{
  sub(/[^:]*:/,"",$1)
  gsub(/^[^<]*|; .*/,"",$4)
  gsub(/^<|>$/,"",$4)
  print $1,$4
}'  Input_file


С показанными образцами, не могли бы вы попробовать следовать, написать и протестировать показанные образцы в GNU awk.

awk '
BEGIN{
  FS = "|"
  OFS = ","
}
{
  val = ""
  for(i=1;i<=NF;i++){
    split($i,arr,":")
    if (arr[1]= = "a" || arr[1]= = "d"){
      gsub(/^[^:]*:|; .*/,"",$i)
      gsub(/^<|>$/,"",$i)
      val=(val?val OFS:"")$i
    }
  }
  print val
}
' Input_file

Объяснение: Добавлено подробное объяснение вышеизложенного.

awk '                                ##Starting awk program from here.
BEGIN{                               ##Starting BEGIN section of this program from here.
  FS = "|"                             ##Setting FS as pipe here.
  OFS = ","                            ##Setting OFS as comma here.
}
{
  val = ""                             ##Nullify val here(to avoid conflicts of its value later).
  for(i=1;i<=NF;i++){                ##Traversing through all fields here
    split($i,arr,":")                ##Splitting current field into arr with delimiter by :
    if (arr[1]= = "a" || arr[1]= = "d"){  ##Checking condition if first element of arr is either a OR d
      gsub(/^[^:]*:|; .*/,"",$i)     ##Globally substituting from starting till 1st occurrence of colon OR from semi colon to everything with NULL in $i.
      val=(val?val OFS:"")$i         ##Creating variable val which has current field value and keep adding in it.
    }
  }
  print val                          ##printing val here.
}
' Input_file                         ##Mentioning Input_file name here. 

Привет, сэр, спасибо за ответ, это работает для этого случая, у меня есть одно сомнение, что если вместо A и D я получил одно и то же имя поля, как и оба значения присутствуют в D: 1 | D: <har: 919876543210 @abc.com>; tag=vy6r5BpcvQ вот так, что мне нужно изменить, так как файл может содержать огромные данные

mark 11.12.2020 08:49

@mark, извините, но это неясно, пожалуйста, приведите более наглядный пример.

RavinderSingh13 11.12.2020 08:50

хорошо, если дело обстоит так: -- a:1|b:2|c:3|a:<har:[email protected]>; тег=vy6r5BpcvQ| если ключ 'a' для первой и четвертой записи

mark 11.12.2020 08:52

@mark, хорошо, так что же тогда будет условием для печати этих значений? Пожалуйста, подтвердите один раз.

RavinderSingh13 11.12.2020 08:57

Я обновлю свой вопрос, я добавлю весь набор данных, которые я получаю

mark 11.12.2020 08:58

@mark, то есть вы всегда хотите печатать 1-й столбец ИЛИ это VAL с одной цифрой, которую вы хотите напечатать? Пожалуйста, подтвердите один раз.

RavinderSingh13 11.12.2020 09:07

Как вы можете видеть в моем примере ввода, есть несколько полей с именем VAL в качестве ключа, я хотел, чтобы его значение присутствовало в первой позиции и 4-й позиции и игнорировало остальные, т.е. 1,<har:[email protected]> , 1 - это значение из первого ключа VAL, а второе - значение из VAL, присутствующего в 4-й позиции, есть много мест, где присутствует VAL, я хочу игнорировать это

mark 11.12.2020 09:12

@mark, пожалуйста, проверьте мой ответ EDIT один раз и дайте мне знать, работает ли это для вас?

RavinderSingh13 11.12.2020 09:18

Да, это сработало, я внес небольшое изменение gsub(/^[^<]*|; .*/,"",$1) sub(/[^:]*:/,"",$4) с этим сработало также, спасибо, сэр

mark 11.12.2020 10:06

Вы также можете попробовать этот скрипт AWK:

cat file

VAL:1|b:2|c:3|VAL:<har:[email protected]>; tag=vy6r5BpcvQ|VAl:1234|name:mnp|VAL:91987654321

awk -F '[|;]' '{
   s = ""
   for (i=1; i<=NF; ++i)
      if ($i ~ /^VAL:/) {
         gsub(/^[^:]+:|[<>]*/, "", $i)
         s = (s == "" ? "" : s "," ) $i
      }
   print s
}' file

1,har:[email protected]

Привет, сэр, спасибо за решение, здесь доступ к полям a и d и выполнение фильтрации, у меня есть одно сомнение, что если вместо двух разных полей a и d ввод изменится на a:1|b:2|c:3 |a:<har:[email protected]>; tag=vy6r5BpcvQ, как это, то как его отфильтровать, так как может быть несколько полей, имя которых начинается с одного и того же поля, например d

mark 11.12.2020 08:57

@mark wrt I have one doubt ... - у вас есть "вопрос", а не "сомнение". Сомнение означает, что вы не верите тому, что вам сказали, вопрос просто означает, что вам нужна информация о чем-то. Это распространенная ошибка в английском языке, на котором говорят в Индии, см. может-сомневаться-иногда-значить-вопрос. Ничего страшного, конечно, просто подумал, что вы хотели бы знать.

Ed Morton 11.12.2020 16:36

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

sed -E 's/^[^:]*:(\w+)[^<]*[<]([^>]+).*$/\1,\2/'

Объяснение

  • 's/find/replace/' стандартная замена, где стоит find;
  • ^[^:]*: с начала пропустить первый ':', затем
  • (\w+) захватить один или несколько символов слова ([a-zA-Z0-9_]), затем
  • [^<]*[<] использовать ноль или более символов не '<', затем '<', затем
  • ([^>]+) захватывать все не '>', а
  • .*$ отбросить все оставшиеся символы в строке, тогда replace
  • \1,\2 повторно вставьте захваченные группы через запятую.

Пример использования/вывода

$ echo 'a:1|b:2|c:3|d:<har:[email protected]>; tag=vy6r5BpcvQ|' | 
sed -E 's/^[^:]*:(\w+)[^<]*[<]([^>]+).*$/\1,\2/'
1,har:[email protected]

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