преобразовать таблицу в запятую, разделенную в текстовом файле, используя bash - PullRequest
0 голосов
/ 31 января 2020

У меня есть такой текстовый файл:

+------------------+------------+----------+
|     col_name     | data_type  | comment  |
+------------------+------------+----------+
| _id              | bigint     |          |
| starttime        | string     |          |
+------------------+------------+----------+

как мне получить такой результат, используя bash

(_id bigint, starttime string   )

, так что только имена столбцов и тип

#remove first 3 lines 
sed -e '1,3d' < columnnames.txt >clean.txt

#remove first character from each line
sed 's/^.//'  < clean.txt >clean.txt

#remove last character from each line
sed 's/.$//' < clean.txt >clean.txt


# remove certain characters 
sed 's/[+-|]//g' < clean.txt >clean.txt 

# remove last line 
sed  '$ d' < clean.txt >clean.txt

так что это то, что у меня есть, если есть лучшая реализация, дайте мне знать!

Ответы [ 6 ]

2 голосов
/ 31 января 2020

Нечто подобное, используя только awk:

awk -F ' *[|]' 'BEGIN {printf("(")} NR>3 && NF>1 {printf("%s%s%s", NR>4 ? "," : "", $2, $3)} END {printf(" )\n")}' columnnames.txt
1 голос
/ 01 февраля 2020
$ awk -F'[| ]+' 'NR>3 && NF>1{v=v s $2" "$3; s=", "} END{print "("v")"}' file
(_id bigint, starttime string)
1 голос
/ 31 января 2020
# Set the field separator to vertical bar surrounded by any number of spaces.
# BEGIN and END blocks print the opening and closing parens
# The line between skips the header lines and any line starting with '+'

$ awk -F"[[:space:]]*[|][[[:space:]]*" '
    BEGIN { printf "%s", "( "}  
    NR > 3 && $0 !~ /^[+]/ { printf("%s%s %s", c, $2, $3); c = ", " } 
    END { print " )" }' file

( _id bigint, starttime string )
0 голосов
/ 01 февраля 2020

Вариант для других ответов с использованием awk с разделителем полей , представляющим собой '|' с необязательными пробелами с обеих сторон, как позволяет GNU awk, затем принимает поля 2 и 3 как поля, требуемые в каждой записи, и форматирование вывода, как описано в вопросе, с закрывающим " )", указанным в правиле END:

$ awk -F' *\\| *' '
    NR>3 && $1~/^[+]/{exit}                 # exit condition first line w/^+
    NR==4{$1=$1; printf "(%s %s", $2,$3}    # 1st data record is 4
    NR>4{$1=$1; printf ", %s %s", $2,$3}    # process all remainng records
    END{print "  )"}                        # output closing "  )"
' table
(_id bigint, starttime string  )

( примечание: если вам не нужны два пробела перед закрытием ")", просто удалите их из print в правиле END)

Вместо использования BEGIN первой записи Проценты (4) используются для обеспечения открытия "(". Посмотрите вещи и дайте мне знать, если у вас есть вопросы.

0 голосов
/ 01 февраля 2020

Другой способ реализации D iego Решение Торреса Милано в качестве отдельной программы awk:

tableconvert

#!/usr/bin/env -S awk -f

BEGIN {
  FS="[[:space:]]*[|][[[:space:]]*"
  printf "%s", "( "
}

{
  if (FNR <= 3 || match($0, /^[+]/))
    next
  else {
    printf("%s%s %s", c, $2, $3)
    c = ", "
  }
} 

END {
  print " )" 
}

Make tableconvert исполняемый файл:

chmod +x tableconvert

Запуск tableconvert на intablefile.txt

./tableconvert intablefile.txt 
( _id bigint, starttime string )

С дополнительным бонусом, что использование FNR вместо NR позволяет программе awk обрабатывать несколько входных файлов в качестве аргументов:

./tableconvert infille1.txt infile2.txt infile3.txt ...
0 голосов
/ 31 января 2020

Я бы сделал это:

cat input.txt \
| tail -n +4 \
| awk -F'[^a-zA-Z_]+' '{ for(i=1;i<=NF;i++) { printf $i" " }}' 

Это немного короче.

...