2015-05-11 1 views
0

Я искал несколько дней, пытаясь использовать awk, sed, cut и tr для возможного решения моей проблемы. У меня есть набор данных, Thats разделителями с «@», как показано ниже ...Как разделить целое число, используя условие «если»?

[email protected]@[email protected]/[email protected]/[email protected]@11/2 
[email protected]@31 1/[email protected] 1/[email protected]/[email protected]@21/2 
[email protected]@116 1/[email protected]@911 3/[email protected]@38 1/2 
[email protected]@[email protected]/[email protected]/[email protected]@49 1/4 
[email protected]@[email protected]@67 1/[email protected] 1/[email protected] 1/2 
[email protected]@[email protected] 1/[email protected] 1/[email protected] 1/[email protected] 
[email protected]@[email protected] 1/[email protected] 1/[email protected]@717 3/4 
[email protected]@127 3/[email protected] 3/[email protected] 1/[email protected] 1/[email protected] 3/4 
[email protected]@[email protected] 64 1/[email protected]@916 1/[email protected] 
[email protected]@139 3/[email protected] 1/[email protected]@[email protected] 3/4 
[email protected]@[email protected]@43 1/[email protected] 1/[email protected] 1/4 
[email protected]@84 1/[email protected]@1011 3/[email protected] 1/[email protected] 1/4 
[email protected]@52 1/[email protected] 1/[email protected]@[email protected] 3/4 

То, что я хотел бы сделать, это разделить число строк в первом столбце (Ряды) от остальных чисел в других столбцах, начиная с столбца 3 и далее. Конечные результаты будут выглядеть так:

[email protected]@[email protected]@[email protected]/[email protected]@1/[email protected]@[email protected]@1/2 
[email protected]@[email protected] 1/[email protected]@1 1/[email protected]@1/[email protected]@[email protected]@1/2 
[email protected]@[email protected] 1/[email protected]@[email protected]@11 3/[email protected]@[email protected]@8 1/2 
[email protected]@[email protected]@[email protected]/[email protected]@1/[email protected]@[email protected]@9 1/4 
[email protected]@[email protected]@[email protected]@[email protected] 1/[email protected]@11 1/[email protected]@11 1/2 
[email protected]@[email protected]@[email protected] 1/[email protected]@9 1/[email protected]@13 1/[email protected]@16 
[email protected]@[email protected]@[email protected] 1/[email protected]@13 1/[email protected]@[email protected]@17 3/4 
[email protected]@[email protected] 3/[email protected]@9 3/[email protected]@12 1/[email protected]@16 1/[email protected]@17 3/4 
[email protected]@[email protected]@[email protected] 1/[email protected]@[email protected]@16 1/[email protected]@18 
[email protected]@[email protected] 3/[email protected]@11 1/[email protected]@[email protected]@[email protected]@19 3/4 
[email protected]@[email protected]@[email protected]@[email protected] 1/[email protected]@18 1/[email protected]@26 1/4 
[email protected]@[email protected] 1/[email protected]@[email protected]@11 3/[email protected]@19 1/[email protected]@28 1/4 
[email protected]@[email protected] 1/[email protected]@3 1/[email protected]@[email protected]@[email protected]@32 3/4 

Я думал, что могу использовать инструкцию «if». Что-то вроде «если целые числа начинаются с [2-9], а затем разделяются после одного символа, elif он начинается с [1], а длина равна 3 или более (перед пространством и дробью), а затем разделяет первые два символа». Я понятия не имею, как решить эту проблему. У меня есть тысячи похожих файлов, и мне нужно изменить структуру для всех из них, поэтому решение придется запускать через цикл.

+0

Вы бросаете слишком много данных. Пожалуйста, покажите 4 или 5 номеров, а затем как их следует разделить. –

ответ

1

Вот одно удовольствие:

perl [email protected] -lape '$_ = join "@", shift(@F), shift(@F), map {s/(1\d|\d)(\d+)/$1\@$2/g; $_} @F' file 

С небольшим комментарием

perl [email protected] -lape ' 
    $_ = join "@",    # join the following things, using "@" 
       shift(@F),   # the first field 
       shift(@F),   # the second field 
       map {    # then, transform the rest with this expr 
        s{    #  search for: 
         (1\d | \d) #  1 plus a digit, or a digit 
         (\d+)  #  followed by one or more digits 
        }{$1\@$2}xg; #  add an "@" in between 
        $_    #  and return the new string 
       } @F 
' file 

Варианты:

  • -a и [email protected] - разделить каждую строку в массив @F используя @ символ в качестве разделителя
  • -l - ручка линии окончаний автоматически
  • -p - автоматически распечатывает переменную $_ после обработки каждой строки
0

Вот в значительной степени транскрипция логики, как вы описали ее в awk (я добавил предположение, что начиная с 1 и имея длину 2 следует разбить после первого символа). Я также заметил, что в строке 9 было пространство после разделителя @, поэтому добавили эту возможность в разделитель полей, как вы можете видеть в блоке BEGIN --- возможно, с реальными данными, которые вам не нужны, так что просто осознанный. В конце концов, я получил ожидаемый результат, но, вероятно, вы хотите проверить это на больших наборах данных, если не будут приняты во внимание другие случаи использования.

$ cat jd.awk 
BEGIN { FS = " *@ *"; OFS = "@" } 

{ 
    for (i=3; i<=NF; ++i) { 
     # if integers start with [2-9] then split after one character 
     if (substr($i, 1, 1) ~ /[2-9]/) { 
      $i = substr($i, 1, 1) "@" substr($i, 2) 
     } 
     else { 
      split($i, parts, "[ /]") 

      # else if it starts with [1] and length is equal to 2 
      # (before the space and fraction) then split the first character 
      if (substr($i, 1, 1) == "1" && length(parts[1]) == 2) { 
       $i = substr($i, 1, 1) "@" substr($i, 2) 
      } 

      # else if it starts with [1] and length is equal to 3 or more 
      # (before the space and fraction) then split the firsts two characters. 
      else if (substr($i, 1, 1) == "1" && length(parts[1]) >= 3) { 
       $i = substr($i, 1, 2) "@" substr($i, 3) 
      } 
     } 
    } 
    print 
} 

$ cat jd.txt 
[email protected]@[email protected]/[email protected]/[email protected]@11/2 
[email protected]@31 1/[email protected] 1/[email protected]/[email protected]@21/2 
[email protected]@116 1/[email protected]@911 3/[email protected]@38 1/2 
[email protected]@[email protected]/[email protected]/[email protected]@49 1/4 
[email protected]@[email protected]@67 1/[email protected] 1/[email protected] 1/2 
[email protected]@[email protected] 1/[email protected] 1/[email protected] 1/[email protected] 
[email protected]@[email protected] 1/[email protected] 1/[email protected]@717 3/4 
[email protected]@127 3/[email protected] 3/[email protected] 1/[email protected] 1/[email protected] 3/4 
[email protected]@[email protected] 64 1/[email protected]@916 1/[email protected] 
[email protected]@139 3/[email protected] 1/[email protected]@[email protected] 3/4 
[email protected]@[email protected]@43 1/[email protected] 1/[email protected] 1/4 
[email protected]@84 1/[email protected]@1011 3/[email protected] 1/[email protected] 1/4 
[email protected]@52 1/[email protected] 1/[email protected]@[email protected] 3/4 


$ awk -f jd.awk jd.txt 
[email protected]@[email protected]@[email protected]/[email protected]@1/[email protected]@[email protected]@1/2 
[email protected]@[email protected] 1/[email protected]@1 1/[email protected]@1/[email protected]@[email protected]@1/2 
[email protected]@[email protected] 1/[email protected]@[email protected]@11 3/[email protected]@[email protected]@8 1/2 
[email protected]@[email protected]@[email protected]/[email protected]@1/[email protected]@[email protected]@9 1/4 
[email protected]@[email protected]@[email protected]@[email protected] 1/[email protected]@11 1/[email protected]@11 1/2 
[email protected]@[email protected]@[email protected] 1/[email protected]@9 1/[email protected]@13 1/[email protected]@16 
[email protected]@[email protected]@[email protected] 1/[email protected]@13 1/[email protected]@[email protected]@17 3/4 
[email protected]@[email protected] 3/[email protected]@9 3/[email protected]@12 1/[email protected]@16 1/[email protected]@17 3/4 
[email protected]@[email protected]@[email protected] 1/[email protected]@[email protected]@16 1/[email protected]@18 
[email protected]@[email protected] 3/[email protected]@11 1/[email protected]@[email protected]@[email protected]@19 3/4 
[email protected]@[email protected]@[email protected]@[email protected] 1/[email protected]@18 1/[email protected]@26 1/4 
[email protected]@[email protected] 1/[email protected]@[email protected]@11 3/[email protected]@19 1/[email protected]@28 1/4 
[email protected]@[email protected] 1/[email protected]@3 1/[email protected]@[email protected]@[email protected]@32 3/4 
0

Это может работать для вас (GNU СЭД):

sed -r 's/^(([^@]*@){2})/\1\n/;ta;:a;/\n[0-9]?$/s/\n//;t;/\n(1[0-9]|[0-9])([0-9][0-9]?)/s//\[email protected]\2\n/;ta;/\n([0-9]?[^0-9\n]) ?/s//\1\n/;ta' file 

Это вставляет новую строку, следующую за вторым полем, а затем совпадения и циклы шаблонов, каждый последующий матч перемещает новую строку вперед, пока конец строки при удалении новой строки.

0

Благодарим вас за все ваши быстрые ответы.
Они помогли мне разобрать мои наборы данных, которые необходимо выполнить перед загрузкой. Решение, которое я закончил использовать, было основано на жемчуге из-за простоты. Еще раз спасибо за ваши ответы.