Добавьте конкретные строки к массиву sed/awk/grep

У меня есть это

ciscoFlashCopyStatus OBJECT-TYPE
        SYNTAX  INTEGER
                {  
                copyOperationPending(0),
                copyInProgress(1),
                copyOperationSuccess (2),
                copyInvalidOperation (3),
                copyInvalidProtocol (4),
                copyInvalidSourceName (5),
                copyInvalidDestName (6),
                copyInvalidServerAddress (7),
                copyDeviceBusy (8),
                copyDeviceOpenError (9),
                copyDeviceError (10),
                copyDeviceNotProgrammable (11),
                copyDeviceFull (12),
                copyFileOpenError (13),
                copyFileTransferError(14),
                copyFileChecksumError(15),
                copyNoMemory (16),
                copyUnknownFailure(17),
                copyInvalidSignature(18)
                }
        MAX-ACCESS      read-only
        STATUS  current     

Что я хочу сделать

Некоторая команда для копирования каждого названия VARIABLE в названный массив var

Так пример вывода

echo "${var[0]}
copyOperationPending

echo "${var[1]}
copyInProgress

echo "${var[2]}
copyOperationSuccess

and so on..

Какие-либо идеи, как я могу достигнуть этого?

ПРИМЕЧАНИЕ. Это - своего рода подобный вопрос, который я задал ранее, как когда-либо somethings изменились, и я больше не могу использовать то же решение, предоставленное в старом вопросе.

2
задан 30 June 2015 в 14:27

5 ответов

Используя grep:

mapfile -t var < <(grep -Po '^\s+\K[^ ]+(?= ?\(\d+\),?$)' file.txt)
  • grep -P будет использовать PCRE (Perl Совместимое Регулярное выражение)

  • grep -o распечатает подобранную часть строки

  • ^\s+\K будет соответствовать строкам, запускающимся с пробелов и \K отбросит соответствие

  • [^ ]+ будет соответствовать нашей желаемой части

  • (?= *\(\d+\)) положительная нулевая ширина, предусматривают нуль обеспечения шаблона или одно пространство, сопровождаемое (, одна или несколько цифр, ) и нуль или один , в конце после нашего желаемого соответствия

  • mapfile оболочка, встроенная, используемая для создания массива.

    $ mapfile -t var < <(grep -Po '^\s+\K[^ ]+(?= ?\(\d+\),?$)' file.txt)
    
    $ echo "${var[0]}"
    copyOperationPending
    
    $ echo "${var[1]}"
    copyInProgress
    
    $ echo "${#var[@]}"
    19
    
6
ответ дан 2 December 2019 в 01:25

Для определенного файла Вы показываете, если Вы просто хотите строки, запускающиеся с copy, достаточно сделать:

var=( $(grep -o 'copy[^(]*' file) )

Вы имеют:

$ for((i=0;i<${#var[@]};i++)); do echo "${var[i]}"; done
copyOperationPending
copyInProgress
copyOperationSuccess
copyInvalidOperation
copyInvalidProtocol
copyInvalidSourceName
copyInvalidDestName
copyInvalidServerAddress
copyDeviceBusy
copyDeviceOpenError
copyDeviceError
copyDeviceNotProgrammable
copyDeviceFull
copyFileOpenError
copyFileTransferError
copyFileChecksumError
copyNoMemory
copyUnknownFailure
copyInvalidSignature
2
ответ дан 2 December 2019 в 01:25

Вы можете grep только строки с полями и использовать sed для удаления всего после вводной круглой скобки. Получающийся список слов может использоваться непосредственно для заполнения массива:

var=($(grep input-file ' *[a-zA-Z]\+ \?([0-9]\+)' | sed 's/(.*//'))
echo ${var[1]}

Регулярное выражение, используемое в grep:

  • пространство + *: любое количество пробелов (включая 0)
  • [a-zA-Z]\+: любое количество букв (по крайней мере 1)
  • пространство + \?: дополнительное пространство
  • (: левая круглая скобка
  • [0-9]\+: любое количество цифр (по крайней мере 1)
  • ): правая круглая скобка
3
ответ дан 2 December 2019 в 01:25

Используя gawk

var=($(gawk '/{/,/}/ {if ($0 ~ /copy/) {match ($0, "[[:alpha:]]+", a); printf "%s\n",a[0]}}' <your_file>))

Используя perl

var=($(perl -ne 'if (/copy/) {s/\s*([[:alpha:]]*).*/$1/g; printf "%s\n",$_}' <your_file>))

Пример

awk

$ var=($(gawk '/{/,/}/ {if ($0 ~ /copy/) {match ($0, "[[:alpha:]]+", a); printf "%s\n",a[0]}}' foo))

$ for((i=0;i<${#var[@]};i++)); do echo "${var[i]}"; done
copyOperationPending
copyInProgress
copyOperationSuccess
copyInvalidOperation
copyInvalidProtocol
copyInvalidSourceName
copyInvalidDestName
copyInvalidServerAddress
copyDeviceBusy
copyDeviceOpenError
copyDeviceError
copyDeviceNotProgrammable
copyDeviceFull
copyFileOpenError
copyFileTransferError
copyFileChecksumError
copyNoMemory
copyUnknownFailure
copyInvalidSignature

perl

$ var=($(perl -ne 'if (/copy/) {s/\s*([[:alpha:]]*).*/$1/g; printf "%s\n",$_}' foo))

$ for((i=0;i<${#var[@]};i++)); do echo "${var[i]}"; done
copyOperationPending
copyInProgress
copyOperationSuccess
copyInvalidOperation
copyInvalidProtocol
copyInvalidSourceName
copyInvalidDestName
copyInvalidServerAddress
copyDeviceBusy
copyDeviceOpenError
copyDeviceError
copyDeviceNotProgrammable
copyDeviceFull
copyFileOpenError
copyFileTransferError
copyFileChecksumError
copyNoMemory
copyUnknownFailure
copyInvalidSignature

cat foo

ciscoFlashCopyStatus OBJECT-TYPE
        SYNTAX  INTEGER
                {  
                copyOperationPending(0),
                copyInProgress(1),
                copyOperationSuccess (2),
                copyInvalidOperation (3),
                copyInvalidProtocol (4),
                copyInvalidSourceName (5),
                copyInvalidDestName (6),
                copyInvalidServerAddress (7),
                copyDeviceBusy (8),
                copyDeviceOpenError (9),
                copyDeviceError (10),
                copyDeviceNotProgrammable (11),
                copyDeviceFull (12),
                copyFileOpenError (13),
                copyFileTransferError(14),
                copyFileChecksumError(15),
                copyNoMemory (16),
                copyUnknownFailure(17),
                copyInvalidSignature(18)
                }
        MAX-ACCESS      read-only
        STATUS  current 
1
ответ дан 2 December 2019 в 01:25

awk метод:

ARRAY=($(awk 'BEGIN{ORS=" "} /SYNTAX/ && /INTEGER/,/MAX-ACCESS/ {gsub(/SYNTAX|INTEGER|MAX-ACCESS.*|[[:blank:]]|{|}/,"");gsub(/\(/," (");for (i=1;i<=NR;i++) {if ($i~/\(|\)/) $i="" };print}' testfile.txt))

Объяснение:

  • Мы настраиваем МАССИВ = (…) структура с $ замены команды (…) в нем для ловли вывода внутренней команды awk в массив.
  • Распечатайте все от строки, которая имеет СИНТАКСИС и ЦЕЛОЕ ЧИСЛО в нем (для предотвращения случаев, где существует неизвестная сумма пространства между СИНТАКСИСОМ и ЦЕЛЫМ ЧИСЛОМ) до МАКС. ДОСТУПА.
  • удалите слова СИНТАКСИС, ЦЕЛОЕ ЧИСЛО, МАКС. ДОСТУП и независимо от того, что следует за ним, удалите пустые строки и эти две фигурных скобки.
  • Замените переменные от переменной (1) к переменной (1), т.е. разделите их с пространством. В этой точке мы имеем, повреждают те поля в два.
  • Пройдите, чтобы цикл нашел поля, которые имеют фигурные скобки и удаляют их. Можно ли спросить, что, если поле содержит пробелы, как (1) или (1)? Разве это не удалило бы только (1 в последнем примере? Ну, мы удалили пробелы перед этим шагом, таким образом, это должно быть безопасно.

  • Наконец распечатайте все, расположите с интервалами разделенный вместо новой строки по умолчанию для выходного разделителя записей. Все, что печатается, входят в массив.

Упрощение

Давайте поместим все в awk сценарий:

#!/usr/bin/awk -f
BEGIN{ORS=" "} 

/SYNTAX/ && /INTEGER/,/MAX-ACCESS/ {
   gsub(/SYNTAX|INTEGER|MAX-ACCESS.*|[[:blank:]]|{|}/,"");
   gsub(/\(/," (");
   for (i=1;i<=NR;i++) {
        if ($i~/\(|\)/) $i="" 
   };
print }

Сохраните делают тот исполняемый файл сценария и работают как так:

$ ARRAY=($(./varscript.awk testfile.txt ))                                                                               


$ echo ${ARRAY[0]}
copyOperationPending


$ echo ${ARRAY[1]}                                                                                                       
copyInProgress


$ echo ${ARRAY[*]}                                                                                                       
copyOperationPending copyInProgress copyOperationSuccess copyInvalidOperation copyInvalidProtocol copyInvalidSourceName copyInvalidDestName copyInvalidServerAddress copyDeviceBusy copyDeviceOpenError copyDeviceError copyDeviceNotProgrammable copyDeviceFull copyFileOpenError copyFileTransferError copyFileChecksumError copyNoMemory copyUnknownFailure copyInvalidSignature
2
ответ дан 2 December 2019 в 01:25

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

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