1
votes

Fusionner 3 colonnes en 1

J'ai 1 fichier csv avec 16 colonnes qui ressemble à ceci:

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

J'ai essayé de fusionner 3 colonnes avec awk et sed mais pour une raison quelconque, je n'obtiens toujours pas le désir sortie:

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

quand j'ai essayé awk -F "|" '{print $ 1, "|" $ 2, $ 3, $ 4, "|" $ 5 ...}'

pour une raison quelconque, des espaces sont ajoutés dans chaque | et voici le résultat que j'obtiens

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

des idées?


1 commentaires

Quels sont vos résultats souhaités? "," peut ne pas être nécessaire.


6 Réponses :


0
votes

Bien que vos exigences ne soient pas claires, mais en voyant votre exemple de sortie attendu, j'ai appris que vous ne vouliez pas d'espace dans la sortie attendue si tel est le cas, vous devez définir OFS comme | comme suit. Écrit et testé avec 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


0 commentaires

1
votes

Vous pouvez joindre les colonnes 2,3 et 4 comme ceci, mais cela vous laissera avec les colonnes 3 et 4 vides:

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

Cela peut être résolu en imprimant les seuls premiers champs fixes, et la boucle à travers le reste.

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 

Vous pouvez supprimer une colonne vide comme ceci, mais s'il y a une colonne vide dans l'original, elles ont disparu aussi:

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


0 commentaires

0
votes

Vous avez dit avoir essayé avec awk et sed ; cependant vous n'êtes pas lié à ceux-ci, vous pouvez utiliser read .

Example:

#!/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

Input:

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

Ouptut:

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

NB La partie exécutable est juste là en tant que "meilleure pratique", vous pouvez obtenir le même résultat sans elle

E.G.

#!/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>&-


1 commentaires

en lecture est pathologiquement lent dans Bash. Vous voulez vraiment préférer un outil approprié comme sed ou Awk.



4
votes

La virgule dans Awk print ajoute un séparateur de champ OFS . Pour concaténer simplement les chaînes, omettez les virgules.

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

Une meilleure approche est probablement de définir OFS = "|" et de simplement déplacer les troisième et quatrième champs, comme expliqué dans Existe-t-il un moyen de supprimer complètement les champs dans awk afin que les délimiteurs supplémentaires ne s'impriment pas?


0 commentaires

2
votes

Avec bash et GNU sed:

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

Explication:

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

se développe en

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

(voir accolade expansion ); il remplace donc le deuxième tube par un espace deux fois , donc les 2ème, 3ème et 4ème champs seront fusionnés.


0 commentaires

1
votes

sed avec les quatre premiers champs correspondants:

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

affichera:

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"


0 commentaires