2015-01-12 5 views
1

Для преобразования строки в Таб-разделителями, легкоКак конвертировать несколько строк в фиксированной колонке длиной

cat input.txt | tr "\n" " "

Но у меня есть длинный файл с 84046468 строк. Я хочу преобразовать это в файл с 1910147 строками и 44 столбцами с разделителями табуляции. Первый столбец представляет собой текстовую строку, такую ​​как chrXX_12345_+, а остальные 43 столбца - это числовые строки. Есть ли способ выполнить это преобразование?

Есть NA s, поэтому я думаю, sed и подставляя «\ n» для «\ t», если строка, предшествующая числу, не работает.

образец input.txt

chr10_1000103_+ 
0.932203 
0.956522 
1 
0.972973 
1 
0.941176 
1 
0.923077 
1 
1 
0.909091 
0.9 
1 
0.916667 
0.8 
1 
1 
0.941176 
0.904762 
1 
1 
1 
0.979592 
0.93617 
0.934783 
1 
0.941176 
1 
1 
0.928571 
NA 
1 
1 
1 
0.941176 
1 
0.875 
0.972973 
1 
1 
NA 
0.823529 
0.51366 
chr10_1000104_- 
0.952381 
1 
1 
0.973684 

образец output.txt

chr10_1000103_+ 0.932203 (numbers all tab-delimited) 
chr10_1000104_- etc 
(sorry alot of numbers to type manually) 
+1

Предоставьте несколько образцов ввода. Вы можете попробовать 'xargs': например,' seq 10 | xargs -n4' присоединятся к блокам по 4 элемента в строке. То же самое происходит с 'seq 10 | паста - - - -. – fedorqui

+1

'xargs' потрясающий! Узнал что-то новое сегодня спасибо! Выход имеет странный разделитель '^ M'. Хорошо, я нашел ответ. [link] (http://unix.stackexchange.com/questions/32001/what-is-m-and-how-do-i-get-rid-of-it) :) – Turtle

+1

Как вы думаете, вы могли бы продемонстрировали вашу проблему, скажем, с четырьмя столбцами вместо 44, поэтому у вас не было бы столько ввода текста, и у нас не было бы столько чтения? «Ответы», опубликованные до сих пор, смехотворно сложны, и я подозреваю, что это потому, что большинство людей не могут потрудиться, чтобы прочитать ваш вопрос. Если вы разместите какой-то разумный ввод проб и фактический ожидаемый результат, я ожидаю, что вы получите правильный ответ, который почти наверняка будет крошечным однострочным awk-скриптом. –

ответ

0

Не самое лучшее решение, но должно работать:

line="nonempty"; while [ ! -z "$line" ]; do for i in $(seq 44); do read line; echo -n "$line "; done; echo; done < input.txt 

Если есть пустая строка в файл, он завершится. Для более постоянного решения я бы попробовал perl.


редактировать:

Если вы обеспокоены эффективностью, просто использовать AWK.

awk '{ printf "%s\t", $1 } NR%44==0{ print "" }' < input.txt 

Вы можете раздеться косым символ табуляции с | sed 's/\t$//' или сделать сценарий AWK более сложным.

+0

Awesome. Это работает без необходимости 'sed -e 's/^ M $ //' < input.txt > output.txt' – Turtle

+0

Он также будет разделять ведущие/конечные пробелы от линий и удалять обратную косую черту и добавлять конечные пустые символы и быть НЕМЕДЛЕННО неэффективными. –

+1

В конце каждой строки awk оставит трейлинг-вкладку. Как насчет '' {printf "% s", $ 1} NR% 44 == 0 {print ""} else {printf "\ t"} '', чтобы он печатал каждую строку, следующую либо с помощью вкладки, либо с новой строки (но не оба)? –

1
sed ' 
# use a delimiter 
s/^/M/ 
:Next 
# put a counter 
s/^/i/ 
# test counter 
/^\(i\)\{44\}/ !{ 
    $ !{ 
# not 44 line or end of file, add the next line 
     N 
# loop  
     b Next 
     } 
    } 

# remove marker and counter 
s/^i*M// 
# replace new line by tab 
s/\n/  /g' YourFile 

некоторые Limite, если более 255 таб на СЭД (так 44 нормально)

1

Вот правильный подход с использованием 4 колонок вместо 44:

$ cat file 
chr10_1000103_+ 
0.932203 
0.956522 
1 
chr10_1000104_- 
0.952381 
1 
1 

$ awk '{printf "%s%s", $0, (NR%4?"\t":"\n")}' file 
chr10_1000103_+ 0.932203  0.956522  1 
chr10_1000104_- 0.952381  1  1 

Просто измените 4 до 44 лет для ваш реальный вход.

Если вы видите контрольные точки в своем выходе, это потому, что они присутствуют на вашем входе, поэтому используйте dos2unix или аналогичный, чтобы удалить их перед запуском инструмента или с помощью GNU awk, вы можете просто установить -v RS='\n\r'.

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

BTW, cat input.txt | tr "\n" " " является UUOC и должно быть просто tr "\n" " " < input.txt

0

Это может работать для вас (GNU СЭД):

sed '/^chr/!{H;$!d};x;s/\n/\t/gp;d' file 

Если строка не начинается с chr добавить его в трюма а затем удалите его, если он не является последним. Если линия запустится chr или последняя строка, затем поменяйте местами удержания и замените все новые строки на вкладках и распечатайте результат.

N.B. начало следующей строки будет оставлено нетронутым в пространстве шаблонов, которое станет новым пространством удержания.

Смежные вопросы