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

2 Manuel [2011-01-04 20:53:00]

У меня есть что-то вроде файла 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 в порядке.

format awk sed csv


4 ответа


5 Решение SiegeX [2011-01-04 21:04:00]

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

16 Fred Foo [2011-01-04 21:30:00]

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

column -t -s@

Он создает пробелы, но не вкладки (и это должно быть, потому что вкладки устарели). Выход:

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

1 Bruce Snow [2015-09-04 02:37:00]

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

#!/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 Sarpdoruk Tahmaz [2011-01-04 21:04:00]

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

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