Как удалить символ новой строки в конкретном столбце файла CSV?

В Сетевая платформа Killer E2200 и Linux он гласит:

[...] Серия E2200 поддерживается ядром Linux 3.10 и выше. [...]

[.. .] В ядре 3.10 порт E2205 так же быстр, как и стандартный гигабитный порт, и никаких проблем не возникало. [...]

4
07.05.2018, 19:25
7 ответов
awk '/Baker/{printf "%s ",$0; getline; printf "%s\n", $0} \
/Penny/{printf $0; getline; printf "%s\n", $0}' file

001|Baker St. London|3|4|7
002|Penny LaneLiverpool|88|5|7
-1
27.01.2020, 20:46

Если первая строка вашего CSV-файла верна, следующий код будет работать.

awk  'NR==1{printf "%s",$0; gsub(/[^|]/,""); nlast=n=length($0); next;} nlast==n{printf "\n";nlast=0} {printf "%s",$0; gsub(/[^|]/,""); nlast+=length($0)} END{print ""}'  file_201805072030.csv > temp.csv && mv -f temp.csv file_201805072030.csv

если ни одна из строк неверна, и если вы хотите изменить порядок с 5 столбцами

awk  'NR==1{printf "%s",$0; gsub(/[^|]/,""); nlast=n=4; next;} nlast==n{printf "\n";nlast=0} {printf "%s",$0; gsub(/[^|]/,""); nlast+=length($0)} END{print ""}' file_201805072030.csv > temp.csv && mv -f temp.csv file_201805072030.csv
1
27.01.2020, 20:46

Если мы можем предположить, что любая строка с двумя полями должна быть удалена из завершающей новой строки, вы можете сделать следующее в Perl:

$ perl -F"\|" -lane '$#F==1 ? printf : print' file.csv 
001|Baker St.London|3|4|7
002|Penny LaneLiverpool|88|5|7

Важный отказ от ответственности :, как указано в комментариях Stéphane Chazelas, это предполагает, что ваш ввод не содержит никаких %символов, поскольку, если это так, они будут приняты в качестве спецификатора формата для printf. Это может иметь непредвиденные последствия, начиная от простого вывода неправильного вывода и заканчивая потреблением загрузок ОЗУ, если ваш ввод имеет что-то глупое вроде %02147483600f%02147483600f%02147483600f%02147483600f.

Пояснение

  • -a:заставляет perlдействовать как awk, разбивая каждую входную строку на символ, заданный -F(, поэтому здесь |;который необходимо экранировать как \|, так как |означает ИЛИ в регулярных выражениях perl )и сохранение результата в виде массива @F.
  • -l:это удаляет завершающие символы новой строки из каждой входной строки и добавляет 'nt к каждому вызову print.
  • -ne:прочитать входной файл построчно и применить сценарий, заданный -e, к каждой строке.
  • $#F==1 ? printf : print':Переменная $#F— это количество элементов в массиве @F, то есть количество полей. Следовательно, это означает, что если количество полей равно 1, тоprintf(будет печатать текущую строку без символа новой строки, поскольку существующий был удален с помощью -l, а printfне добавляет один ). Если количество полей не точно равно 1, printстрока (, которая из-за -lдобавит новую строку ).

То же самое можно расширить до:

$ perl -e 'while($line=<STDIN>){
            chomp $line; 
            @fields=split(/\|/,$line); 
            if(scalar(@fields) == 2){
                print "$line";
            } 
            else{
                print "$line\n"
            }
           }' < file.csv 
001|Baker St.London|3|4|7
002|Penny LaneLiverpool|88|5|7

И еще более короткая версия, предложенная @Sundeep в комментариях:

perl -F'\|' -ape 'chomp if $#F==1'
1
27.01.2020, 20:46

Еще одно решение GNU awk, использующее 4 раза |на запись:

awk -v RS='([^|]+\\|){4}[^|]+\n' '{gsub(/\n/," ",RT); print RT}' file

RSустанавливается так, что запись содержит 4 разделителя (даже с новой строкой ).

RTловит рекорд, установленный RS. gsubудаляет новую строку в записи.

2
27.01.2020, 20:46

С помощью инструмента sedвы можете сделать так, как показано на рисунке:

sed  -i  -e '
             /^\(\([^|]*|\)\{2\}\)*[^|]*$/b
             N;s/\n/ /
             s/^/\n/;D
   '    . /*.csv

Пояснение:

  1. Переход к концу обработки кода sedдля текущих данных пространства шаблонов, когда найдено четное количество конвейеров.

  2. Или выберите следующую строку и добавьте ее в пространство шаблонов.

  3. Теперь снова примените код sedк пространству шаблонов.

     perl -i.BAK    -lpe '
         $\ = ( $k += tr/|/|/ ) =~ /[24680]$/ ? "\n" : " ";
      '    . /*.csv 
    
  4. $k— текущий счетчик количества труб, которые можно увидеть в любое время.

  5. Ибо даже мы печатаем с новой строкой, в противном случае мы соединяем строки пробелом.

0
27.01.2020, 20:46

На основе формата 1-го поля (при условии, что каждая строка должна начинаться с цифры):

awk 'NR == 1{ printf $0; next }
     { printf "%s%s", (/^[0-9]+/? ORS : ""), $0 }
     END{ print "" }' file.csv

Выход:

001|Baker St.London|3|4|7
002|Penny LaneLiverpool|88|5|7
3
27.01.2020, 20:46

Вы можете использовать sedдля объединения следующей строки с текущей, если текущая строка не содержит 4 |символов:

<file sed -e :1 -e 's/|/|/4;t' -e 'N;s/\n/ /;b1'

В некоторых реализациях sedесть -iили -i ''для редактирования файлов в -место(-i.backдля сохранения оригинала с расширением .back), так что с ними вы можете сделать:

sed -i -e :1 -e 's/|/|/4;t' -e 'N;s/\n/ /;b1'./*.csv

Для редактирования всех не -скрытых csvфайлов в текущем каталоге.

То же с комментариями:

<file sed '
   :1
     s/|/|/4; # replace the 4th | with itself. Only useful when combined with
              # the next "t" command which branches off if the previous
              # substitution was successful
     t
     # we only reach this point if "t" above did not branch off, that is
     # if the pattern space does not contain 4 "|"s
     N; # append the next line to the pattern space
     s/\n/ /; # replace the newline with a space

   # and then loop again in case the pattern space still does not contain
   # 4 "|"s:
   b1'
7
27.01.2020, 20:46

Теги

Похожие вопросы