2015-03-30 4 views
2

У меня есть выход uniq -c, который выводит около 7-10 строк с подсчетом каждого шаблона, который повторялся для каждого уникального шаблона линии. Я хочу сохранить вывод моего файла uniq -c file.txt в массив bash. Прямо сейчас все, что я могу сделать, это сохранить вывод в переменной и распечатать его. Однако bash в настоящее время думает, что весь вывод - это только одна большая строка.Получение вывода команды оболочки в bash array

Как bash распознает разделители? Как вы храните вывод команд оболочки UNIX в виде массивов Bash?

Вот мой текущий код:

proVar=`awk '{printf ("%s\t\n"), $1}' file.txt | grep -P 'pattern' | uniq -c` 
echo $proVar 

И токовый выход я получаю:

587 chr1 578 chr2 359 chr3 412 chr4 495 chr5 362 chr6 287 chr7 408 chr8 285 chr9 287 chr10 305 chr11 446 chr12 247 chr13 307 chr14 308 chr15 365 chr16 342 chr17 245 chr18 252 chr19 210 chr20 193 chr21 173 chr22 145 chrX 58 chrY 

Вот что я хочу:

proVar[1] = 2051 
proVar[2] = 1243 
proVar[3] = 1068 
... 
proVar[22] = 814 
proVar[X] = 72 
proVar[Y] = 13 

В конечном счете, я м надеясь сделать штрих-код на основе подсчетов для каждого индекса, где каждые 50 отсчетов равны одному знаку «=». Он будет, надеюсь, выглядеть следующим образом:

chr1 =========== 
chr2 =========== 
chr3 ======= 
chr4 ========= 
... 
chrX == 
chrY = 

Любая помощь, ребята?

+0

Возможно, вам действительно нужны массивы bash, но я делаю свои гистограммы в конце конвейера с awk, то есть 'awk '/ pattern/{printf ("% s \ t \ n "), $ 1}' file .txt | сортировать | uniq -c | awk '{fn_mkThatHistogram ($ 0)}' ', но YRMV. Удачи! – shellter

+0

Использование 'grep -P' в сочетании с' awk' довольно странно. Учитывая, что 'perl' является более вездесущим, чем' grep', который поддерживает '-P', почему бы просто не использовать' perl' для первых двух частей трубы? –

+0

Чтобы ответить на ваш вопрос, это потому, что я не знал, что Perl является командой unix (ха-ха), и я не знаю много о Perl в целом. Меня обучали в основном в C и UNIX, поэтому я обычно придерживаюсь популярных команд UNIX для сценариев bash. Я использовал параметр -P, чтобы иметь возможность регулярного выражения для форматирования строк с помощью \ t \ n, а что нет. Я обязательно посмотрю на Perl! – areyoujokingme

ответ

3

Чтобы построить ассоциативный массив, попробуйте следующее:

declare -A proVar 
while read -r val key; do 
    proVar[${key#chr}]=$val 
done < <(awk '{printf ("%s\t\n"), $1}' file.txt | grep -P 'pattern' | uniq -c) 

Примечание: Это предполагает, что выход вашего командования состоит из нескольких линий, каждая из которых содержит пару один ключ-значение; однострочный вывод, показанный в вашем вопросе, исходит от прохождения $proVar для эха без двойных кавычек.

  • Использует while петлю, чтобы читать каждую выходную линию от замещения процесса (<(...)).
  • ключ для каждого ассоциированного партнера. запись массива формируется путем удаления префикса chr из первого элемента, разделенного пробелами, в каждой строке ввода, тогда как значение - это остальная часть строки (после разделительного пространства).

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

while IFS= read -r key; do 
    echo "chr${key} $(printf '=%.s' $(seq $((${proVar[$key]}/50))))" 
done < <(printf '%s\n' "${!proVar[@]}" | sort -n) 

Примечание: Использование sort -n для сортировки ключей поместит ключи нецифровых такие как X и Yперед числовыми на выходе ,

  • $((${proVar[$key]}/50)) вычисляет количество = символов.для отображения, используя целое число деление в арифметическом расширении.
  • Цель $(seq ...) состоит в том, чтобы просто создать столько жетонов (аргументы), как = символы. (маркеры, созданные как цифры, но их содержимое не имеет значения).
  • printf '=%.s' ... - это трюк, который эффективно печатает как можно больше символов =. так как есть аргументы, следующие за строкой формата.
  • printf '%s\n' "${!proVar[@]}" | sort -n сортирует ключи партнера. массив, а его выход подается через подстановку процесса в цикл while, который поэтому выполняет итерации по ключам в отсортированном порядке.
+0

Вы феноменальны - спасибо! Я так много узнал из вашего кода и объяснений. Вы бы сделали отличного инструктора. :-) – areyoujokingme

+0

@areyoujokingme: Мое удовольствие; это очень мило с вашей стороны. Разрешите мне этот общий совет: в интересах как респондентов, так и будущих читателей: если ответ _solves_ ваша проблема, пожалуйста _accept it_, нажав на большой флажок рядом с ним; если вы найдете ответ _helpful_, пожалуйста, запустите его, щелкнув значок стрелки вверх. (Вы можете сделать оба.) – mklement0

+1

Я спал прошлой ночью, понимая это - спасибо за напоминание! Я не часто спрашиваю, что нужно принимать ответы. Еще раз спасибо! – areyoujokingme

0

Вы можете создать массив в уступке с помощью круглых скобок:

proVar=(`awk '{printf ("%s\t\n"), $1}' file.txt | grep -P 'pattern' | uniq -c`) 

Там нет встроенного способа создать ассоциативный массив непосредственно от входа. Для этого вам понадобится дополнительный цикл.

+0

Это создает массив, но не с правильными ключами или значениями. – Swiss

+0

Я не думаю, что есть способ создать ассоциативный массив непосредственно из вывода, я думаю, вам придется написать цикл для этого. – Barmar

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