awk / sed / и т. д. конкатенация колонок в одном файле

Интересно, что более простой способ сделать это:

awk 'NR > 1 {print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\t"$8"\t"$9$10$11$12$13$14$15$16}' file.in > file.out 

который, просто говоря, «объединяет столбцы с 9 по 16 путем удаления вкладок между ними»,

Объединенные столбцы 9-16 становятся «заметками», поэтому могут включать пробелы.

На сегодняшний день существует 16 столбцов, но при необходимости они могут развиваться более / менее. В конце концов столбец 9 (конкатенированный 9-16) становится полем «примечания».

Ура,
Xi

6 Solutions collect form web for “awk / sed / и т. д. конкатенация колонок в одном файле”

 paste <(cut -f 1-8 file) <(cut -f9- file | tr -d '\t') 

Предполагая несколько строк отделимых от нуля значений, генерируемых таким образом:

 % perl -E 'say join "\t", 1..8 for 1..3' 

Затем различные столбцы можно обрабатывать по мере необходимости с помощью соответствующих флагов и переменных и функций, доступных в Perl.

 % perl -E 'say join "\t", 1..8 for 1..3' \ | perl -pale '$_=join "\t", @F[0..3], join "", @F[4..7] if $. > 1' 1 2 3 4 5 6 7 8 1 2 3 4 5678 1 2 3 4 5678 % 

Да, много способов. Я проверил следующие два файла, созданного:

 perl -le 'next if $.==1; for(1..20){print join "\t",1..20 }' > file 

Это файл с 20 строками и 20 столбцами с разделителями столбцов.

  1. Perl

     perl -F'\t' -ale '$"="\t";print "@F[0..7]",@F[8..$#F]' file 

    Обратите внимание, что это объединяет все поля с 10-го до конца. Если вы хотите присоединиться только к 9 к 16, используйте вместо этого:

     perl -F'\t' -ale '$"="\t"; print "@F[0..7]", @F[8..15], "\t@F[16..$#F]"' file 
  2. AWK

     awk -F'\t' 'NR>1{ for(i=1;i<9;i++){ printf "%s\t",$i } for(i=9;i<=NF;i++){ printf "%s",$i }print "" }' file 

    Как и раньше, это будет соединяться со всеми столбцами после 10-го. Если вы хотите присоединиться только к 9 к 16, используйте вместо этого:

     awk -F'\t' 'NR>1{ for(i=1;i<9;i++){ printf "%s\t",$i } for(i=9;i<=16;i++){ printf "%s",$i } for(i=17;i<=NF;i++){ printf "\t%s", $i } print "" }' file 

Конечно, решения awk не очень короткие, но по крайней мере вам не нужно указывать все поля вручную.

Альтернатива Python

 $ cat file | python -c "import sys for line in sys.stdin: l=line.rstrip('\r\n').split('\t'); print('\t'.join(l[:9]) + ''.join(l[9:])) " 

альтернативный вариант

 s/(([^\t]*\t){8})/\1\n/ h s/[^\n]*\n// s/\t//g G s/([^\n]*)\n([^\n]*)\n.*/\2\1/ 

Пример использования:

 $ sed -r "s/(([^\t]*\t){8})/\1\n/;h;s/[^\n]*\n//;s/\t//g;G;s/([^\n]*)\n([^\n]*)\n.*/\2\1/" file 

Объяснение:

Предположим, что file

 abcdefghijkl 

Разделителем в file является вкладка.

  1. sed читает текущую строку.

    • пространство рисунка – abcdefghijkl
  2. s/(([^\t]*\t){8})/\1\n/ разбивает линию на две части.

    • пространство рисунка – abcdefgh \ni jkl
  3. h хранит пространство в пространстве удержания.

    • пространство рисунка – abcdefgh \ni jkl
    • пространство пробела abcdefgh \ni jkl
  4. s/[^\n]*\n// удаляет первую часть в пространстве шаблонов.

    • пространство рисунка – ijkl
    • пространство пробела abcdefgh \ni jkl
  5. s/\t//g удаляет вкладки в пространстве шаблонов.

    • пространство рисунка – ijkl
    • пространство пробела abcdefgh \ni jkl
  6. G добавляет \n и удерживает пространство в пространстве шаблонов.

    • пространство рисунка ijkl\na bcdefgh \ni jkl
    • пространство пробела abcdefgh \ni jkl
  7. s/([^\n]*)\n([^\n]*)\n.*/\2\1/ разбивает пространство рисунка и заменяет его второй и первой частями без \n .

    • пространство рисунка – abcdefgh ijkl
    • пространство пробела abcdefgh \ni jkl
  8. sed печатает узорное пространство.

Возможно изменить код и удалить вкладки в средних столбцах:

 s/(([^\t]*\t){3})(([^\t]*\t){4})(.*)/\1\n\3\n\5/ h s/[^\n]*\n([^\n]*)\n.*/\1/ s/\t//g G s/([^\n]*)\n([^\n]*)\n([^\n]*)\n(.*)/\2\1\4/ 

С помощью GNU sed (при условии, что поля указаны на вкладке на вкладке):

 sed 's/\t//9g' 

Удаляет символы 9-го и последнего вкладок в каждой строке.

Если на входе больше 16 полей, и вам не нужны дополнительные:

 cut -f 1-16 | sed 's/\t//9g' 

AWK:

 awk -v OFS="\t" '{for (i=10; i<=NF; i++) $9 = $9 " " $i; NF = 9; print}' file 

Поля 10 до конца добавляются в поле 9, тогда число полей ограничено первым 9, а строка печатается с помощью вкладки в качестве разделителя выходного поля.

Я предполагаю, что вы хотите, чтобы конкатенированные поля были разделены пробелом.
Если нет, измените $9 " " $i до $9 $i

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