(sed / awk) Как преобразовать файл с разделителями полей (например, csv) в txt с фиксированными столбцами с разделителями табуляции? - PullRequest
3 голосов
/ 04 января 2011

У меня есть что-то вроде CSV-файла, в котором разделителем полей является "@".

ID @ Имя @ Фамилия @ Возраст @ Профессия @ адрес

1254343123@John@Smith@24@Engineer@Washington
23@Alexander@Kristofferson-Brown@Economic Advisor@Kent
...

Я хочу преобразовать его во что-то более понятное человеку, как в:

1254343123    John        Smith                  24    Engineer            Washington
23            Alexander   Kristofferson-Brown    35    Economic Advisor    Kent

... где каждый столбец помечается определенным символом.

Я пробовал что-то, что использует значение размера TAB и добавляет несколько TAB к полю:

sed -e "{/@[^@]\{32,\}@/s/@\([^@]*\)@/\t\1\t/g};{/@[^@]\{24,31\}@/s/@\([^@]*\)@/\t\1\t/g};{/@[^@]\{16,23\}@/s/@\([^@]*\)@/\t\1\t\t/g};{/@[^@]\{8,15\}@/s/@\([^@]*\)@/\t\1\t\t/g};{/@[^@]\{2,7\}@/s/@\([^@]*\)@/\t\1\t\t\t/g}"

... который работает не во всех случаях.

Может ли кто-нибудь дать мне подсказку о том, как действовать?

PS: я собираюсь использовать в основном sed (однострочник) или, если sed просто не обрезает, awk в порядке.

Ответы [ 4 ]

17 голосов
/ 04 января 2011

BSD, Mac OS X и Linux имеют команду column для этого:

column -t -s@

Это создает пробелы, а не табуляции (и должно быть, потому что табуляции устарели).Выход:

1254343123  John       Smith                24  Engineer          Washington
23          Alexander  Kristofferson-Brown  35  Economic Advisor  Kent
6 голосов
/ 04 января 2011
awk -F@ '{for(i=1;i<=NF;i++){printf "%-20s", $i};printf "\n"}' input.csv

Входные данные

$ cat input.csv
1254343123@John@Smith@24@Engineer@Washington
23@Alexander@Kristofferson-Brown@35@Economic Advisor@Kent

Выходные данные

$ awk -F@ '{for(i=1;i<=NF;i++){printf "%-20s", $i};printf "\n"}' input.csv
1254343123          John                Smith               24                  Engineer            Washington
23                  Alexander           Kristofferson-Brown 35                  Economic Advisor    Kent

Если вы хотите сделать ширину поля (20 в коде выше) переменной оболочки, которую можно передать в вассделать что-то вроде этого:

#!/bin/bash

fldwth=20

awk -v fw=$fldwth -F@ '{for(i=1;i<=NF;i++){printf "%-*s", fw,$i};printf "\n"}' input.csv
1 голос
/ 04 сентября 2015

Мое решение для преобразования CSV-файла Excel по умолчанию (с разделителями-запятыми, текст в двойных кавычках) заключается в следующем сценарии awk:

#!/bin/nawk -f
# Q&D to transform csv (with commas imbedded in quotes) to pipe (|)
# Usage: cma2pipe.awk <in.csv> > <out.csv>
# Note: Assumes that <in.csv> contains no ~ or |  
{#MAIN
  s=$0;c=0;f=0;        #reset varibles for a line
  while (c<length(s)){ #loop thru line
    c++;               #char counter
    a=substr(s,c,1);   #get current character
    if (a=="\"")f++;   #flag quote
    if (f%2==1&&a==",")#if inside pair of quotes, look for ","
      s= repl("~",c,s);#replace commas with ~
  }#end while c
  gsub(",","|",s);     #replace remaining , with |
  gsub("~",",",s);     #put commas back
  gsub("\"","",s);     #get rid of quotes
print s
}#end MAIN
function repl(r,n,t){  #replace single character in string
  s1=substr(t,1,n-1);  #get first part of string
  s2=substr(t,n+1);    #get last part of string
  return(s1 r s2);     #return changed string
}#end repl()
0 голосов
/ 04 января 2011

awk -F@ '{print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6}' file.csv > readable.txt

Попробуйте использовать опцию-разделитель для awk и напечатать столбцы, поставив между ними \t.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...