Объединить 3 столбца в 1 - PullRequest
1 голос
/ 20 октября 2019

У меня есть 1 CSV-файл с 16 столбцами, который выглядит следующим образом:

WEB QUEST|Lazaro|Martinez|0|Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0

Я пытался объединить 3 столбца вместе с awk и sed, но по какой-то причине я все еще не получаю желаемый вывод:

WEB QUEST|Lazaro Martinez 0|Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0

, когда я пытался awk -F "|" '{print $1,"|"$2,$3,$4,"|"$5...}'

, по некоторым причинам в каждом |и это вывод, который я получаю

EB QUEST |Maria Valencia Loza |Consultor de ventas | Mexico |DF | 55457110 | 55450327 | 4003071 | evalencia@webquest.com.mx | 05/10/1999 | 0 |0 |0

есть идеи?

Ответы [ 6 ]

4 голосов
/ 20 октября 2019

Запятая в Awk print добавляет разделитель полей OFS. Чтобы просто объединить строки, пропустите запятые.

awk -F "|" '{print $1 "|" $2 $3 $4 "|" $5...}'

Вероятно, лучший подход - установить OFS="|" и просто сместить третье и четвертое поля, как описано в Есть ли способ полностьюудалить поля в awk, чтобы лишние разделители не печатались?

2 голосов
/ 20 октября 2019

С bash и GNU sed:

sed -e's/|/ /2'{,} file

Объяснение:

-e's/|/ /2'{,}

расширяется до

-e's/|/ /2' -e's/|/ /2'

(см. расширение скобки );поэтому он заменяет второй канал пробелом дважды , таким образом, 2-е, 3-е и 4-е поля будут объединены.

1 голос
/ 20 октября 2019

sed с соответствием первым четырем полям:

sed 's/\([^|]*\)|\([^|]*\)|\([^|]*\)|\([^|]*\)/\1|\2 \3 \4/' <<<"WEB QUEST|Lazaro|Martinez|0|Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0"

выведет:

WEB QUEST|Lazaro Martinez 0|Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0
1 голос
/ 20 октября 2019

Вы можете присоединиться к столбцам 2,3 и 4 следующим образом, но это оставит вас с пустыми столбцами 3 и 4:

awk -F\| -v OFS='|' '{$2=$2" "$3" "$4;$3=$4="";print $0}' file
WEB QUEST|Lazaro Martinez 0|||Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0

Это можно решить, напечатав только первые фиксированные поля, ицикл до конца.

awk -F\| '{a=$2" "$3" "$4;$3=$4="";printf "%s"FS"%s",$1,a;for (i=5;i<=NF;i++) printf FS"%s",$i}' file
WEB QUEST|Lazaro Martinez 0|Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0 

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

awk -F\| -v OFS='|' '{$2=$2" "$3" "$4;$3=$4="";gsub(/[|]+/,FS)}1' file
WEB QUEST|Lazaro Martinez 0|Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0
0 голосов
/ 20 октября 2019

Вы сказали, что пытались с awk и sed;однако вы не привязаны к ним, вы можете использовать read.

Пример:

#!/bin/bash
exec 3<file.csv
while IFS="|" read -r foo var1 var2 var3 bar <&3; do
  printf "%s|%s %s %s|%s\n" "${foo}" "${var1}" "${var2}" "${var3}" "${bar}"
done
exec 3>&-

Ввод:

WEB QUEST|Lazaro|Martinez|0|Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0

Выход:

WEB QUEST|Lazaro Martinez 0|Consultor de ventas|Mexico|DF|55457110|55450327|53445299|0|05/10/1999|0|0|0

NB. Exec - это просто «Лучшая практика», вы можете достичь того же результата без него.

EG

#!/bin/bash
while IFS="|" read -r foo var1 var2 var3 bar; do
  printf "%s|%s %s %s|%s\n" "${foo}" "${var1}" "${var2}" "${var3}" "${bar}"
done <file.csv
0 голосов
/ 20 октября 2019

Хотя ваше полное требование не ясно, но, увидев ожидаемый пример вывода, я узнал, что вы не хотите места в ожидаемом выводе, если это так, тогда вам нужно установить OFS как | следующим образом. Написано и протестировано с GNU awk.

awk '
BEGIN{
  s1=" "
  FS=OFS="|"
  re="(.*)\\|\\|\\|(.*)"
}
prev{
  print gensub(re,"\\1|\\2","1",$0)
}
{
  $2=$2 s1 $3 s1 $4
  $3=$4=""
  prev=$0
}
END{
  if(prev){
    print gensub(re,"\\1|\\2","1",$0)
  }
}
'  Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...