Нужен сценарий Awk или Unix для транспонирования / поворота в следующем шаблоне

Файл содержит данные в следующем формате (первая строка – это заголовок):

N ; A ; B ========= 1 ; 01;02 2; 02;02 

Основываясь на первом столбце, я ожидаю следующий вывод: столбец N остается тем же, однако другие могут расти, это могут быть C, D, E и т. Д., И соответствующие значения могут быть захвачены.

 1;A;01 2;A;02 1:B;02 2;B;02 

Как я могу это сделать?

3 Solutions collect form web for “Нужен сценарий Awk или Unix для транспонирования / поворота в следующем шаблоне”

Вот фрагмент кода с использованием Python …

Код:

 # read in the data with open('data_file', 'rU') as f: # read in the header header = [x.strip() for x in f.readline().split(';')] # drop the ====== dump_marker = f.readline() # get the rest of the data data = [[x.strip() for x in line.split(';')] for line in f.readlines()] # print the data in new format for i, col in enumerate(header[1:]): for line in data: print("{};{};{}".format(line[0], col, line[i+1])) 

файл данных:

 N ; A ; B ========= 1 ; 01;02 2 ; 02;02 

Результат:

 1;A;01 2;A;02 1;B;02 2;B;02 

В bash это можно сделать с помощью внутренних команд, tail и cut :

 #! /bin/bash # Get header line header=$( head -n 1 data_file ) # Make a variable with all delimiters (2) delimiters=${header//[^;]/} # Make an array with all column names declare -a colnames=( ${header//;/ } ) # For all columns one at the time... for C in $(seq 2 $((${#delimiters}+1)) ) ; do index=$((C-1)) # Skip first 3 lines of data_file tail --lines=+3 data_file | cut -d\; -f1,$C | while read; do # Replace first ';' with column name line=${REPLY/;/;${colnames[$index]};} # Remove all spaces and print echo ${line// /} done done 

Объяснение:

Получить первую строку файла в переменной (которая затем может быть изменена)

 header=$( head -n 1 data_file ) 

Удалите все символы из переменной, ожидающей разделитель cemi-colon

 delimiters=${header//[^;]/} 

Теперь переменные $ delimiters содержат ';;'

Заменить все ';' с пробелами. Это даст «НАБ». Одним или несколькими пробелами является разделитель массива:

 declare -a colnames=( ${header//;/ } ) 

Получить количество символов в переменной:

 ${#delimiters} 

Добавить один:

 $((${#delimiters}+1)) 

затем

 $(seq 2 $((${#delimiters}+1)) ) 

равно:

 $(seq 2 3 ) 

Индекс в переменной переходит от 0..n, затем -1 для поиска имен столбцов:

 index=$((C-1)) 

Прочитайте файл, пропустите первые 3 строки, покажите только номер столбца $C , прочитайте строку в переменной $REPLY :

 tail --lines=+3 data_file | cut -d\; -f1,$C | while read; do 

И решение с использованием awk :

 awk -F';' '{ gsub(/ /,"");} NR==1 { cols = split($0, col); } NR > 2 { for (i = 2; i <= cols; i++) { data[col[i]";"$1] = $1";"col[i]";"$i; } } END { no = asorti(data, sorted); for (i = 1; i <= no; i++) { print data[sorted[i]]; } }' input 
  • Объединение совпадающих столбцов с двумя файлами или использование значения по умолчанию
  • читать образцы из файла1 и искать их итеративно в файле2
  • Как извлечь строки между одинаковыми шаблонами из файла
  • Использовать awk в качестве редактора потока
  • Использовать awk, чтобы найти первое вхождение
  • Как я могу выполнить двоичный поиск текстового файла для определенной строки символов?
  • использовать awk для замены скобок?
  • Как удалить символы текста в одной строке перед конкретным символом?
  • Как добавить заголовок и / или нижний колонтитул в поток sed или awk?
  • Как выводить только столбец с постоянными соседями?
  • Найти шаблон и удалить его из всех файлов
  • Отдельные «дублированные строки» по пустой строке
  • Linux и Unix - лучшая ОС в мире.