2017-02-10 47 views
0

У меня есть команда, которая выводит в следующей схемеЧитайте pariticular раздел списка отделен разделителем в массив, используя сценарий оболочки

red 
yellow 
blue 
green 
-------- 
black 
brown 
pink 

Я хотел бы прочитать список перед «----» в один массив, а другой - в другой массив.

Я знаю, что это можно сделать, используя петлю. Но также я думаю, что это можно сделать очень элегантно, используя SED или AWK, и проблема в том, что я не знаю, как это сделать. Я бы очень признателен за любую помощь в этом. Я очень уверен, что это возможно, но, пожалуйста, дайте мне знать, если я ошибаюсь или есть лучший/более умный способ.

+2

Опубликовать свою попытку и с которой вы заблокированы. – Inian

+0

Кроме того, это не простой способ, после выполнения команды вывода, как это происходит, только если у вас нет другого способа контролировать это с помощью вашей исходной команды. – Inian

+0

Хотелось бы узнать больше о происхождении этого вопроса. Каков ваш фактический прецедент? Можем ли мы получить подтверждение того, что (как только вы зададите реальный вопрос), это не проблема [XY] (http://xyproblem.info/)? – ghoti

ответ

3

Начинает с чтения полного списка по массив.

readarray -t tmp < <(yourCommand) 

Затем найдите разделитель.

for ((i=0; i<${#tmp[@]}; i++)); do 
    if [[ ${tmp[i]} == "--------" ]]; then 
     break 
    fi 
done 

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

one=("${tmp[@]:0:i}") 
two=("${tmp[@]:i+1}") 
0

Вы можете попробовать это?

awk 'BEGIN {RS="" } {s=$i" "s } END { split(s,a,"--------"); print a [1],a[2] } ' d 

red 
yellow 
blue 
green 

black 
brown 
pink 

a [1] - верхняя часть. a [2] - нижняя часть.

0

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

#!/bin/bash 
declare -a array1=() 
while IFS= read -r line ; do 
    [[ $line != "--------" ]] || break 
    array1+=("$line") 
done 
readarray -t array2 

Он должен получить свой вклад по стандарту в Положи в сценарии (скажем, split_arrays), сделайте его исполняемым, и назвать это так:.

./split_arrays < <(command) 

Или:

./split_arrays <data_file 
1

Я искал ответ больше как это:

$cat txt 
red 
yellow 
blue 
green 
-------- 
black 
brown 
pink 

затем:

array=$(cat txt | awk '{ if ($1~/----/) exit; else {print $1}}') 
echo $array 

red 
yellow 
blue 
green 
0

Вам не нужно на самом деле какой-либо петли для обработки файла. Эти две команды будут делать трюк:

sed -n '1,/-----/!p' a.txt #Will exclude 1st line up to pattern, excluding also the line with pattern = last part of your file 
sed -n '/-----/,$!p' a.txt #Will exclude pattern line up to last line excluding also the line with pattern = first part of your file 

Вы можете назначить их в разных массивах с readarray техникой:

readarray -t first < <(sed -n '/-----/,$!p' a.txt) 
readarray -t second < <(sed -n '1,/-----/!p' a.txt)  
1

Если ваш файл будет таким

red 
yellow 
blue 
green 
-------- 
black 
brown 
pink 

Затем вы можете:

$ array=$(cat file | grep -v - | tr '\n' ' ') 
$ 
$ echo $array 
$ red yellow blue green black brown pink 
$ 
$ echo ${array:0:21} 
$ red yellow blue green 
$ 
$ echo ${array:22:-1} 
$ black brown pink