Как извлечь определенные значения после определенной строки и сохранить их в разных переменных?

  1. Оболочка POSIX :

    n=0
    while IFS=',' && read x ; do
        set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done < inputfile
    
  2. bashможно более кратко:

     n=0; while IFS=',' read -a x ; do echo "${x[((n++))]}" ; done < inputfile
    

Обратите внимание, что легко получить диагонали для всех четырех поворотов данных путем фильтрации только по tacи rev, (или tac--, если данные представляют собой квадрат . ].csv массив ). Примеры оболочки POSIX , но сначала создайте несколько новых асимметричных входных значений:

seq 25 | paste -d, - - - - - | tee asym_input

Выход:

1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
  1. A\диагональ слева направо , (вопрос OP ,с другим вводом):

    n=0
    while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done < asym_input
    

    Выход:

    1
    7
    13
    19
    25
    
  2. A/слева направо по диагонали:

    n=0
    tac asym_input | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done
    

    Выход:

    21
    17
    13
    9
    5
    
  3. A/справа налево по диагонали:

    n=0
    rev asym_input | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done | rev
    

    Выход:

    5
    9
    13
    17
    21
    
  4. A\справа налево по диагонали:

    n=0
    tac asym_input | rev | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done | rev
    

    Выход:

    25
    19
    13
    7
    1
    
0
16.09.2019, 20:46
2 ответа

Использование awk и eval:

eval "$(awk -F: '{ print $1 "='\''" $2 "'\''" }' tmp)"

Команда внутри $()анализирует файл summary.txt. С опцией -Fмы указываем awk использовать :в качестве разделителя полей. Он форматирует каждую строку следующим образом:

Total_Pass='24'

Мне пришлось экранировать одинарные кавычки ; вот почему код выглядит так уродливо.

eval используется для выполнения форматированного текста точно так же, как вы написали это в своем скрипте. Как вы можете догадаться, это опасно , если у вас нет полного контроля над входными данными. См. Почему в Bash следует избегать использования eval и что следует использовать вместо него? Возможно, кто-то может указать более безопасный способ сделать это.

Затем вы можете использовать свои новые переменные следующим образом:

printf "Total_Pass with value %s\n" "$Total_Pass"
1
28.01.2020, 02:22

Лучше всего это делать с помощью ассоциативного массива. например.

declare -A array

while IFS=: read key val; do
  array["$key"]="$val"
done < input.txt

for key in Total_Test_Cases_Count Total_Pass; do
  printf '%s=%s\n' "$key" "${array[$key]}"
done

Выход:

Total_Test_Cases_Count=25
Total_Pass=24

Это не удастся, если какое-либо из значений содержит разделитель полей (двоеточие,:). В этом случае вам сначала нужно изменить разделитель полей во входных данных на что-то, чего нет ни в одном из полей. Вкладка часто является хорошим выбором. Например:

while IFS=$'\t' read key val; do
  array["$key"]="$val"
done < <(sed -e 's/:/\t/1' input.txt)

IFS настроен на использование табуляции в качестве разделителя, а команда sedзаменяет первый (и только первый )символ двоеточия на табуляцию.

2
28.01.2020, 02:22

Теги

Похожие вопросы