Как переносить текстовый файл на основе символов

Есть некоторые инструменты, такие как datamesh для переноса матрицы в файл csv , но я хочу обмениваться строками и столбцами на основе символов. Итак, файл

 abcde fghij klmn opqrs 

должен стать

 afko bglq chmq dinr ej s 

Обратите внимание, что поскольку строка 3 короче, в последней строке должно быть вставлено пробельное пространство.

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

  • Инструменты Linux для обработки файлов как наборов и выполнения заданных операций над ними
  • Получить номер строки из смещения байта
  • Почему «df» висит?
  • Сохранять вывод команды в кольцевой буфер
  • Сортировка и группирование доменов и поддоменов
  • Выполнение двух действий с выходом команды
  • Есть ли способ сделать perl -i не clobber символические ссылки?
  • установка утилиты column unix для окон
  • 3 Solutions collect form web for “Как переносить текстовый файл на основе символов”

    Вы можете сделать это с помощью утилиты rs в режиме чистого транспонирования ( -T ) – если вы правильно вставляете входные данные, т. Е.

     $ sed -e 's/./& /g' -e 's/ $//' file abcde fghij klmn opqrs 

    (или, если у вас есть GNU sed, вы можете использовать sed 's/./ &/2g' ; другой вариант использует цикл sed -E ':a; s/([^ ])([^ ])/\1 \2/; ta' ); тогда

     $ sed -e 's/./& /g' -e 's/ $//' file | rs -Tng0 afko bglp chmq dinr ej s 

    Важными параметрами являются:

    • -T чисто транспонировать
    • -n pad null entries
    • -g0 установить ширину выходного желоба (межколоночное расстояние) до нуля

    В качестве альтернативы, выполните разделение ввода с помощью awk с пустым разделителем полей ввода и разделителем полей вывода по умолчанию:

     awk '{$1=$1} 1' FS= file | rs -Tng0 

    Следующее общее решение для транспонирования с awk.

    Для правильной работы нам нужно количество столбцов.
    Это можно найти при чтении файла в массив значений:

     #!/bin/bash file=i4 delimiter="" sep="" transpose() { : # comment sed for newer awks. # Do this to separate characters in quite old awk # very old wak does not allow that the FS could be Null. #sed -e 's/./ &/g' "$file" | awk ' { for(i=1;i<=NF;i++){a[NR,i]=$i};{(NF>m)?m=NF:0} } END { for(j=1; j<=m; j++) { for(i=1; i<=NR; i++) { b=((a[i,j]=="")?" ":a[i,j]) printf("%s%s",(i==1)?"":sep,b) } printf("\n") } } ' FS="$delimiter" sep="$sep" cc="$countcols" <"$file" } transpose 

    С этим файлом:

     abc fghij klmn opqrs 

    Будет печать:

     afko bglp chmq inr js 

    Awk позаботится о разделении символов, если «разделитель полей» равен нулю.
    Символы печатаются в одной строке, если переменная sep также равна нулю.


    Если awk является более старым, нулевой FS недействителен. Используйте следующие две команды.

    Чтобы подсчитать количество символов, используйте это в старых awks:

     # Work with any POSIX awk to find the max character count in all rows. countcols=$(awk '{l=length($0);(l>max)?max=l:0}END{print max}' < "$file") 

    Для выполнения транспозиции пространство может быть добавлено перед каждым символом и использовать пробел в качестве «разделителя полей» и избегать пустой FS:

     sed -e 's/./ &/g' < "$file" | awk ' {for(i=1;i<=cc;i++){if($i==""){$i=" "};r[i]=r[i]sep$i;};sep=""}; END{for(i=1;i<=cc;i++)print(r[i])} ' cc="$countcols" для sed -e 's/./ &/g' < "$file" | awk ' {for(i=1;i<=cc;i++){if($i==""){$i=" "};r[i]=r[i]sep$i;};sep=""}; END{for(i=1;i<=cc;i++)print(r[i])} ' cc="$countcols" 

    Прокомментируйте линию sed для новых awks.

    Вот решение с cut и paste . Поскольку у вас нет разделителя, такого как пространство или табулятор, ему нужно некоторое исправление с sed :

     for COL in {1..5}; do cut -c $COL < infile | paste -s -d_ ; done | sed -e 's/__/_ /g' -e 's/_//g' 

    Здесь разбито в многострочном:

     for COL in {1..5}; do cut -c $COL < infile | paste -s -d_ done | sed -e 's/__/_ /g' -e 's/_//g' 

    Результат первой части выглядит так:

     for COL in {1..5}; do cut -c $COL < infile | paste -s -d_ ; done a_f_k_o b_g_l_p c_h_m_q d_i_n_r e_j__s 

    Досадно, что вам нужно знать, сколько столбцов есть до начала.

    Linux и Unix - лучшая ОС в мире.