Как объединить вертикально две строки, полученные с помощью grep? - PullRequest
0 голосов
/ 26 апреля 2019

Я использую команду grep для выбора некоторых полей в файле. Эта команда выбирает N (N = 2 в примере ниже) блоков по 5 разделенных пробелами полей каждый и возвращает переменную, содержащую эту строку, которая называется firstPart:

chr8 aa1 bb1 cc1 dd1 chr8 aa2 bb2 cc2 dd2 

Также второе выполнение grep возвращает строку, содержащую N блоков из 5 разделенных пробелами полей, которая называется secondPart и содержит:

SLC7A2 ee1 ff1 gg1 hhh1 SLC7A2 ee2 ff2 gg2 hhh2

Я хотел бы знать, какую команду bash я мог бы использовать для помещения firstPart и secondPart в массив из N элементов, где первый блок каждого элемента связан с его соответствующим вторым блоком. Выход должен быть:

chr8 aa1 bb1 cc1 dd1 SLC7A2 ee1 ff1 gg1 hhh1
chr8 aa2 bb2 cc2 dd2 SLC7A2 ee2 ff2 gg2 hhh2

Есть идеи у кого-нибудь?

Ответы [ 2 ]

1 голос
/ 26 апреля 2019

Почти наверняка есть лучший способ сделать то, что вы пытаетесь сделать, но, поскольку у вас уже есть ответы на заданный вопрос, вот еще:

$ firstPart='chr8 aa1 bb1 cc1 dd1 chr8 aa2 bb2 cc2 dd2'
$ secondPart='SLC7A2 ee1 ff1 gg1 hhh1 SLC7A2 ee2 ff2 gg2 hhh2'

$ read -r -a fp <<< "$firstPart"
$ read -r -a sp <<< "$secondPart"

$ fmt="$(eval "printf '%%s %.0s' {1..$(( ${#sp[@]} / 2 - 1 ))}")%s\n"

$ paste -d' ' <(printf "$fmt" "${fp[@]}") <(printf "$fmt" "${sp[@]}")
chr8 aa1 bb1 cc1 dd1 SLC7A2 ee1 ff1 gg1 hhh1
chr8 aa2 bb2 cc2 dd2 SLC7A2 ee2 ff2 gg2 hhh2
1 голос
/ 26 апреля 2019

Предупреждение: это ответ на вопрос "если у меня есть две строки N блоков по 5 пустых разделенных слов каждый, как я могу получить массив из N элементов, где каждый элемент i содержит блок i из первой и второй строки? "

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

Вот как я бы решил то, что вы на самом деле спросили в Bash:

#!/usr/bin/env bash

firstPart='chr8 aa1 bb1 cc1 dd1 chr8 aa2 bb2 cc2 dd2'
secondPart='SLC7A2 ee1 ff1 gg1 hhh1 SLC7A2 ee2 ff2 gg2 hhh2'
N=2
for ((i = 0; i < N; ++i)); do
    printf -v arr[i] '%s %s' \
        "$(cut -d ' ' -f $((1 + i * 5))-$((5 + i * 5)) <<< "$firstPart")" \
        "$(cut -d ' ' -f $((1 + i * 5))-$((5 + i * 5)) <<< "$secondPart")"
done

printf '%s\n' "${arr[@]}"

Команда cut расширяется до чего-то вроде

cut -d ' ' -f 1-5

для первых блоков, затем

cutd -d ' ' -f 6-10

для вторых блоков и т. Д. Оператор printf объединяет эти выходные данные и сохраняет их в выходном массиве arr с индексом i.

Выход

chr8 aa1 bb1 cc1 dd1 SLC7A2 ee1 ff1 gg1 hhh1
chr8 aa2 bb2 cc2 dd2 SLC7A2 ee2 ff2 gg2 hhh2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...