2

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

пример файла:

column1  column2  column3
  444      999      000                 
  555      888      xxx 
  666      777      xxx

выходной файл:

output is 444  bla  999  bla  000                   
output is 555  bla  888  bla  xxx   
output is 666  bla  777  bla  xxx 

Я попробовал следующий bash:

readarray -t column <firstcolumn.txt
for i in "${column1[@]}";  do
    readarray -t  column2 <secondcolumn.txt
    for j in "${column2[@]}"; do
        readarray -t column3 <thirdcolumn.txt
        for k in "${column3[@]}";  do
            echo "output is $i bla $j bla $k"
        done
    done
 done

3 ответа3

1

Это простой скрипт, который должен показывать использование readarray . Я держу его более похожим на тот, который вы публикуете.

#!/bin/bash 

awk '{ print $1 }' data.txt  >  file_column1.txt
awk '{ print $2 }' data.txt  >  file_column2.txt
awk '{ print $3 }' data.txt  >  file_column3.txt
# NLines=` wc -l data.txt | awk '{print $1}'`

readarray -t column1 < file_column1.txt
readarray -t column2 < file_column2.txt
readarray -t column3 < file_column3.txt

i=0;
for item in "${column1[@]}"; do
   echo  output is ${column1[$i]} bla ${column2[$i]}  bla ${column3[$i]}; 
   let "i=i+1" 
done

# rm -f file_column1.txt file_column2.txt file_column3.txt

Комментарии:

  • С помощью awk вы можете распечатать желаемый столбец (1 доллар за $1 -й, $2 -й и т.д.).Вы создаете отдельный файл для каждого столбца.
  • Если раскомментировать, строка #Nlines=wc -l | awk '{print $1}' можно использовать для подсчета количества строк для вектора, который будет создан после readarray , и для выполнения цикла другим способом ...
  • С readarray вы читаете один файл и помещаете в 1D вектор.
  • Цикл for включен для каждого компонента 1D векторного столбца1. Это должно быть сделано для каждого вектора, потому что в вашем примере они имеют одинаковый размер. Это должно быть сделано с использованием Nlines .
  • В item неиспользуемой переменной внутри цикла всегда есть одно и то же значение column1 [i]
  • Вы получаете доступ непосредственно к нужному компоненту массива. (Первый индекс равен 0 а последний - Nlines-1)
  • Вы увеличиваете значение i на каждой итерации цикла for .
  • При необходимости раскомментируйте, чтобы стереть временные файлы, созданные в скрипте.

Выход

 output is 444 bla 999  bla 000 
 output is 555 bla 888  bla xxx 
 output is 666 bla 777  bla xxx 

Последний комментарий
Если вы вложите 3 цикла (один внутри другого), вы получите каждую перестановку: не 3, а 3 * 3 * 3 = 27 строк

 0 0 0  
 0 0 1   
 0 0 2   
 0 1 0  
 ...
0

Почему вы не загружаете массивы отдельно от операции, в которой вы их печатаете?

readarray -t column1 <column1.txt
readarray -t column2 <column2.txt
readarray -t column3 <column3.txt

for (( i=0; i<${#column1[@]}; i++ )); do
    echo -e "output is ${column1[$i]} bla ${column2[$i]} bla ${column3[$i]}"
done
0

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

while read col1 col2 col3; do
    echo "output is $col1  bla  $col2  bla  $col3"
done < file

Или, чтобы пропустить заголовок:

tail -n +2 file | while read col1 col2 col3; do     
    echo "output is $col1  bla  $col2  bla  $col3"; 
done 

Если вы действительно нуждаетесь в них в массиве, попробуйте что-то вроде

i=0; 
while read col1 col2 col3; do 
    col1s[$i]=$col1; 
    col2s[$i]=$col2; 
    col3s[$i]=$col3; 
    let i++; 
done < <(tail -n +2 file); 
k=0;
for(( k=0; k<i; k++ )); do 
    echo "output is ${col1s[$k]} blah ${col2s[$k]} blah ${col3s[$k]}"; 
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .