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

У меня есть файл с разделителями табуляции с номером и именами, принадлежащими одному и тому же номеру в одной строке. Номер и имена разделены вкладкой. Имена связаны между собой двумя подчеркиваниями (__). Это выглядит так:

33  Hhe.1__Hhe.2__Hhe.3__Hhe.4

Я хотел бы преобразовать его (используя командную строку) в этот вывод:

33  Hhe.1
33  Hhe.2
33  Hhe.3
33  Hhe.4
3
задан 12 April 2016 в 12:15

5 ответов

С awk:

$ awk -F '\t|__' '{for (i=2;i<=NF;i++) {printf "%s\t%s\n", $1, $i}}' foo.txt 
33  Hhe.1
33  Hhe.2
33  Hhe.3
33  Hhe.4
  • Мы разделяем строки на поля на основе вкладки (\t) или двух символов нижнего подчеркивания (__).
  • Затем, мы циклично выполняемся по полям от второго до последнего, и печатаем каждого снабженного префиксом первое поле и вкладку.
0
ответ дан 12 April 2016 в 22:15
  • 1
    Это стирает раздел подкачки? I' m означают меня don' t должны использовать GParted всегда? – Francisco 22 August 2017 в 09:31

Подобный, к какой предложенный muru: что относительно того, чтобы разделить второе поле на основе __ и затем цикличное выполнение через части?

awk 'BEGIN{FS=OFS="\t"}
     {n=split($2,a,"__"); for (i=1;i<=n;i++) print $1, a[i]}' file

Это использует то, что split() возвраты созданное число элементов.

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

Это возвращается:

33  Hhe.1
33  Hhe.2
33  Hhe.3
33  Hhe.4
0
ответ дан 12 April 2016 в 22:15

Можно использовать остроту жемчуга для этого:

perl -ane '@l=split(/__/,$F[1]); foreach $val (@l){print $F[0],"\t",$val,"\n"}'

Пример:

$ echo "33  Hhe.1__Hhe.2__Hhe.3__Hhe.4" | perl -ane '@l=split(/__/,$F[1]); foreach $val (@l){print $F[0],"\t",$val,"\n"}'
33  Hhe.1
33  Hhe.2
33  Hhe.3
33  Hhe.4

Объяснение команд использовало:

perl -ane                    #read input line-wise and split line on tab
'@l=split(/__/,$F[1]);       #split the second element ($F[1]) on a double _
foreach $val (@l){           #for each value, print the first element and the value.
  print $F[0],"\t",$val,"\n"
 }'
4
ответ дан 12 April 2016 в 22:15
  • 1
    Нет, это не удаляет физический раздел, просто деактивирует его. Изменение размеров разделов с данными по ним опасно, если Вам действительно не нужно то дополнительное пространство, если не тогда Вам не был бы нужен Gparted здесь. – Kris Stadler 22 August 2017 в 09:36

Еще одна острота жемчуга:

$ perl -lane 'print "$F[0]\t$_" for split(/__/,$F[1])' file 
33  Hhe.1
33  Hhe.2
33  Hhe.3
33  Hhe.4

Это - та же основная идея, как существующий Perl отвечает, только короче. -a автоматически разделения каждая строка входного файла на пробелах и делают получающиеся поля доступными как массив @F. Так, $F[0] 1-е поле, $F[1] второе и так далее. -n означает, "читает каждый входной файл линию за линией и применяют сценарий, данный -e. -l удаляет запаздывание \n символы от каждой входной строки и добавляют a \n каждому print звонить.

split(/__/,$F[1]) создает массив путем разделения 1-го поля файла на символах __. Так, print "$F[0]\t$_" for split... выполнит итерации по массиву, возвращенному split назовите и распечатайте первое поле файла ($F[0]), символ табуляции \t и текущее поле split массив.

1
ответ дан 12 April 2016 в 22:15
  • 1
    It' s не невозможный удалить тот раздел, it' s просто опасный для удаления его, когда другие данные и разделы присутствуют на том же диске. Gparted будет в состоянии помочь Вам с изменением размеров, но помнить, что шанс процесс мог повредить некоторые данные по диску в процессе, высоко если не сделанный правильно. – Kris Stadler 22 August 2017 в 09:49

Другой способ использовать Perl:

perl -lane '$,="\n"; print(map($F[0] . "\t" . $_, split("__", $F[1])))' file
perl -lane '
    $,="\n";
    print(map($F[0] . "\t" . $_, split("__", $F[1])))
' file
  • -l[octnum]: включает автоматическую заканчивающую строку обработку. Это имеет два отдельных эффекта. Во-первых, это автоматически чавкает $/ (входной разделитель записей) при использовании с -n или -p. Во-вторых, это присваивается $\ (выходной разделитель записей) иметь значение octnum так, чтобы любые операторы печати имели тот разделитель, включило назад. Если octnum опущен, наборы $\ к текущему значению $/.
  • -a: включает режим авторазделения при использовании с a -n или -p. Неявное разделение управляет к @F массив сделан как первая вещь в неявном цикле с условием продолжения, произведенном -n или -p.
  • -n: Perl причин для принятия следующего цикла вокруг программы, которая заставляет его выполнить итерации по аргументам имени файла несколько как sed -n или awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
    
  • -e: может использоваться для ввода одной строки программы;

  • $,="\n"; print(map($F[0] . "\t" . $_, split("__", $F[1]))); устанавливает выходного разделителя полей на символ новой строки, разделяет второе поле на __ и предварительно ожидает первое поле, сопровождаемое табулированием к каждому подполю, наконец печатая запись.
% cat file
33  Hhe.1__Hhe.2__Hhe.3__Hhe.4
% perl -lane '$,="\n"; print(map($F[0] . "\t" . $_, split("__", $F[1])))' file
33  Hhe.1
33  Hhe.2
33  Hhe.3
33  Hhe.4
3
ответ дан 12 April 2016 в 22:15
  • 1
    Но я стер бы его, и я не коснусь корневого.. таким образом, какова может быть проблема? – Francisco 22 August 2017 в 09:38

Другие вопросы по тегам:

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