Замените файл, разделенный запятыми, на вертикальную черту, но не удаляйте запятую или кавычки и т. д. в поле текстового квалификатора, однако удалите текстовый квалификатор!

Замените файл, разделенный запятыми, на вертикальную черту, но не удаляйте запятую или кавычки и т. д. в поле текстового квалификатора, однако удалите текстовый квалификатор!

Мой файл представляет собой файл с разделителями-запятыми, а текстовый квалификатор — ~, но мне нужно найти и заменить файл с разделителями-запятыми на файл с разделителями |(вертикальная черта) и удалить текстовый квалификатор ~ ничем, однако мне не следует удалять кавычки или двойные кавычки или любые специальные символы в данных, присутствующих в текстовом квалификаторе. Например: ~abc",~ Мне нужно как abc",

Ниже приведено содержимое моего исходного файла и то, каким я ожидаю получить выходной или обработанный файл.

Исходный файл:

364034,2015652205,26722,2015,4,~C25753-4~,~TC25753,~,~2WD Double Cab 144.2" SLT,~,~Y~,40506.16,43555.00,1095.00,~043,005,006,007,003,008,016,041,012,029,068,027,028,033~,3,~2WD Double Cab 144.2"~,~SLT~,6,4,~N~,~S~,~N~,~S~,~N~,~N~,~N~,~~,~ ~,~Confirmed~,~w2015k65m22t5~,~Sierra 2500HD~,~Double Cab Standard Box 2-Wheel Drive SLT~,~Rear Wheel Drive~,~Extended Cab Pickup - Standard Bed~

После очистки мне нужен такой файл:

364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043|005|006|007|003|008|016|041|012|029|068|027|028|033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

Я попробовал sed -i -e с несколькими параметрами, но вывод не на 100% правильный.

Я попробовал следовать, но это не дало нужного мне результата.

sed -i -e 's/,~/|/g' file_name
sed -i -e 's/~,/|/g' file_name
sed -i -e 's/~//g' file_name
sed -i -e 's/\([0-9],[0-9]\)/|/g' file_name
sed -i -e 's/\r//g' file_name

решение1

ESC=$(printf '\033')
RED="${ESC}[0;31m"
 NC="${ESC}[0m"

sed -e '
   /./!b
   /[^[:space:]]/!b

   s/.*/\
&,/

   :loop
      h
      s/\(\n\),/|\1/;                                                  # An empty field
      s/\(\n\)\([+-]\{0,1\}[.][0-9]\{1,\}\),/\2|\1/;                   # +-.NNN
      s/\(\n\)\([+-]\{0,1\}[0-9]\{1,\}\([.][0-9]*\)\{0,1\}\),/\2|\1/;  # +-NNN.MMM +-NNN. +-NNN
      s/\(\n\)~\([0-9][0-9]*\),/\2|\1/;                                # ~NNN
      s/\(\n\)\([0-9][0-9]*\)~,/\2|\1/;                                # NNN~
      s/\(\n\)~\([^~]*\)~,/\2|\1/;                                     # ~...~
      x;G
      /^\(.*\)\n\1$/{
         g;'"s/\n\([^,]*\)/${RED}\1${NC}/"'
         i\
***'"${RED}ERROR${NC}"'*** Unable to process the field shown colored.\
\
Cause of error: What this means is that this particular field is not \
\
           Fix: You should add to the sed code in the :loop label to \
                digest the able to be processed by the sed code as it stands.\
\
The record with the offending field shown colored red:\

         q
      }
      g; # all clear: recover and carry on...
   /\n$/!bloop

   s/..$//
' csv.data

Работающий

  • Мы основываем решение на различных типах полей.
  • Пропускайте пустые или незаполненные строки.
  • Добавьте «,» для упрощения регулярного выражения, мы уберем его в конце.
  • Чтобы запустить мяч, мы ставим маркер, \n, в начале строки. Этот маркер будет перемещаться слева направо, перепрыгивая поле, обработанное за раз.
  • Действие начинается в do-whileцикле, в теле которого мы обрабатываем одно поле за раз. Начало поля сигнализируется \nи мы обрабатываем различные разновидности полей, которые могут возникнуть. Каждый раз мы переносим обработанное поле влево от \nи заменяем ,на |.
  • Цикл останавливается, когда маркер \nдостигает конца линии /\n$/, и мы убираем маркер, а также манекен, ,который мы поместили в начале.

Полученные результаты

364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043|005|006|007|003|008|016|041|012|029|068|027|028|033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

решение2

Я бы посоветовал использовать специальный парсер CSV, например PerlТекст::CSV

perl -MText::CSV -lne '
    BEGIN{ $csv = Text::CSV->new({ quote_char => "~" , escape_char => "~" , allow_whitespace => 1}) } 
    print join "|", $csv->fields() if $csv->parse($_)
  ' file_name
364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043,005,006,007,003,008,016,041,012,029,068,027,028,033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

Связанный контент