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

Для файловой системы ext4 команда

sudo debugfs /dev/sda1 <<<"blocks /boot/vmlinuz-3.11.0-14-generic"

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

1
задан 12 April 2016 в 12:15

4 ответа

Вы можете использовать однострочный perl для этого:

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
ответ дан 23 May 2018 в 12:13

Другой способ использования 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: включается режим автосброса при использовании с -n или -p. Неявная команда split для массива @F выполняется как первая вещь внутри неявного цикла while, созданного -n или -p. -n: заставляет Perl предполагать следующий цикл вокруг вашей программы, что заставляет его перебирать аргументы имени файла несколько как sed -n или awk:
LINE:
  while (<>) {
      ...             # your program goes here
  }
-e: может использоваться для ввода одной строки программы; [F22]; устанавливает разделитель выходного поля символом новой строки, разбивает второе поле на __ и добавляет первое поле, за которым следует табуляция к каждому подполе, окончательно печатая запись.
% 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
ответ дан 23 May 2018 в 12:13

Еще один perl однострочный:

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

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

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

1
ответ дан 23 May 2018 в 12:13

Похоже на то, что предложил 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
1
ответ дан 23 May 2018 в 12:13

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

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