Заполнение пробела / табуляция разделены, пустые столбцы с 0 - PullRequest
2 голосов
/ 11 января 2011

У меня огромный файл, и в качестве вывода некоторые столбцы не имеют значения, мне нужно заполнить эти столбцы 0 для дальнейшего анализа.Я могу разделить столбцы пробелом или табуляцией, теперь под ними видно разделение табуляцией.

alt text

Ответы [ 5 ]

6 голосов
/ 11 января 2011

Для файла, разделенного табуляцией, этот фрагмент кода AWK добивается цели:

BEGIN { FS = "\t"; OFS="\t" }
{
    for(i = 1; i <= NF; i++) {
         if(!$i) { $i = 0 }
    }
    print $0
}
6 голосов
/ 11 января 2011

Это действительно работа для синтаксического анализатора CSV, но если это должно быть регулярное выражение, и у вас никогда не будет вкладок в цитируемых записях CSV, вы можете найти

(^|\t)(?=\t|$)

и заменить на

$10

Итак, в Perl:

(ResultString = $subject) =~ 
s/(    # Match either...
   ^   # the start of the line (preferably)
   |   # or
   \t  # a tab character
  )    # remember the match in backreference no. 1
  (?=  # Then assert that the next character is either
   \t  # a(nother) tab character
   |   # or
   $   # the end of the line
  )    # End of lookahead assertion
/${1}0/xg;

Это преобразует

1   2       4           7   8
    2   3       5   6   7   

в

1   2   0   4   0   0   7   8   
0   2   3   0   5   6   7   0
1 голос
/ 12 января 2011

Вот решение sed.Обратите внимание, что некоторые версии sed не любят \t.

sed 's/^\t/0\t/;:a;s/\t\t/\t0\t/g;ta;s/\t$/\t0/' inputfile

или

sed -e 's/^\t/0\t/' -e ':a' -e 's/\t\t/\t0\t/g' -e 'ta' -e 's/\t$/\t0/' inputfile

Объяснение:

s/^\t/0\t/    # insert a zero before a tab that begins a line
:a            # top of the loop
    s/\t\t/\t0\t/g    # insert a zero between a pair of tabs
ta            # if a substitution was made, branch to the top of the loop
s/\t$/\t0/    # insert a zero after a tab that ends a line
1 голос
/ 11 января 2011

Удаление моего ответа после перечитывания исходного поста.Там нет вкладок в качестве данных, только разделители.Если данных нет, для выравнивания столбцов появится двойной разделитель.
Другого пути быть не может.Таким образом, если есть один разделитель, он разделит два пустых поля."" = 1 пустое поле, "\ t" = 2 пустых поля.Теперь я понял.

У Тима Пицкера всегда был правильный ответ.+1 для него.
Это можно записать альтернативно как s/ (?:^|(?<=\t)) (?=\t|$) /0/xg;, но это то же самое.

0 голосов
/ 09 июля 2019

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

awk 'BEGIN{FS=OFS="\t"}{for(i=1;i<=NF;++i) $i+=0}1' file

Добавляя ноль, мы конвертируем строки в числа. Пустые строки будут преобразованы в ноль. Вы можете определить свой разделитель полей для чего угодно.

Это, однако, может быть немного медленным, так как он будет повторно обрабатывать $0 и разбивать его на поля каждый раз, когда вы переназначаете поле $i.

Более быстрый путь - это решение Деннис Уильямсон

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