awk сохраняет результат шаблона в переменной массива оболочки

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

#!/bin/bash declare -a array1=() declare -a array2=() READ_FILE="directory1/read_file.csv" WRITE_FILE="directory2/results.csv" #variable for counting array index count1=0 count2=0 # # # need help with line below # $2 below is the second set of characters which is a floating point number awk -F 'string1_to_search' '{$array1[count1++] = $2}' $READ_FILE >> $WRITE_FILE awk -F 'string2_to_search' '{$array2[count1++] = $2}' $READ_FILE >> $WRITE_FILE #count++ indicates post increment of count variable

любые предложения были бы полезны.

3
задан 7 January 2018 в 20:23

3 ответа

Вы не можете писать переменные Bash изнутри awk.

Вместо этого вы должны сделать awk распечатать все, что вы хотите сохранить в массиве, по одному элементу в строке, а затем используйте встроенный Bash mapfile, чтобы прочитать его в массив:

mapfile -t array1 < <( awk -F 'string1_to_search' '{print $2}' "$READ_FILE" )

После этого ваш массив находится в $array1. Вам также не нужно declare заблаговременно, mapfile делает это для вас.

Более подробную информацию о mapfile можно найти, набрав help mapfile.

Боковое замечание: вместо перебора awk ... | mapfile ... я использовал перенаправленную замену процесса mapfile ... < <( awk ... ), потому что вы не можете использовать mapfile как часть конвейера. Это связано с тем, что конвейеры выполняются в подоболочках, которые не распространяют свои измененные переменные обратно на родительскую оболочку, то есть значение myarray будет потеряно.

3
ответ дан 22 May 2018 в 15:42
  • 1
    Что делать, если значение, отправленное массиву, является числом? Я пытаюсь сделать операцию сокращения на элементе массива, но я получаю сообщение об ошибке, и мне кажется, что элемент анализируется как строка, а не число – gajendra 8 January 2018 в 00:33
  • 2
    Насколько мне известно, Bash не различает строки и числа в переменных / массивах, все обрабатывается как строка. Просто команды могут пытаться интерпретировать эти строки как числа. Не могли бы вы дать более подробную информацию о том, что вы пытаетесь сделать, например, о реальных командах, а также проверить правильность содержимого массива? Возможно, вы также должны задать это в новом вопросе, где вы можете добавить ссылку на этот контекст. Если вы оставите мне комментарий здесь, как только вы разместите его, я пойду и посмотрю. – Byte Commander 8 January 2018 в 00:38

Вы не можете писать переменные Bash изнутри awk.

Вместо этого вы должны сделать awk распечатать все, что вы хотите сохранить в массиве, по одному элементу в строке, а затем используйте встроенный Bash mapfile, чтобы прочитать его в массив:

mapfile -t array1 < <( awk -F 'string1_to_search' '{print $2}' "$READ_FILE" )

После этого ваш массив находится в $array1. Вам также не нужно declare заблаговременно, mapfile делает это для вас.

Более подробную информацию о mapfile можно найти, набрав help mapfile.

Боковое замечание: вместо перебора awk ... | mapfile ... я использовал перенаправленную замену процесса mapfile ... < <( awk ... ), потому что вы не можете использовать mapfile как часть конвейера. Это связано с тем, что конвейеры выполняются в подоболочках, которые не распространяют свои измененные переменные обратно на родительскую оболочку, то есть значение myarray будет потеряно.

3
ответ дан 17 July 2018 в 23:40

Вы не можете писать переменные Bash изнутри awk.

Вместо этого вы должны сделать awk распечатать все, что вы хотите сохранить в массиве, по одному элементу в строке, а затем используйте встроенный Bash mapfile, чтобы прочитать его в массив:

mapfile -t array1 < <( awk -F 'string1_to_search' '{print $2}' "$READ_FILE" )

После этого ваш массив находится в $array1. Вам также не нужно declare заблаговременно, mapfile делает это для вас.

Более подробную информацию о mapfile можно найти, набрав help mapfile.

Боковое замечание: вместо перебора awk ... | mapfile ... я использовал перенаправленную замену процесса mapfile ... < <( awk ... ), потому что вы не можете использовать mapfile как часть конвейера. Это связано с тем, что конвейеры выполняются в подоболочках, которые не распространяют свои измененные переменные обратно на родительскую оболочку, то есть значение myarray будет потеряно.

3
ответ дан 24 July 2018 в 17:04

Другие вопросы по тегам:

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