Извлекая строку из строки, введите в качестве входных данных команду и затем выведите всю строку с заменой строки - PullRequest
1 голос
/ 23 октября 2019
  1. У меня есть файл, содержащий как показано ниже, есть несколько строк

    test1| 1234 | test2 | test3
    
  2. Извлеките второй столбец 1234 и запустите команду, подающую это как ввод

  3. Допустим, мы получаем X в качестве вывода для команды
  4. Вывести вывод, как показано ниже для каждой строки

    test1 | X | test2 | test3
    

Предпочитаю, чтобы я мог делать это в одной строке, но открыт для идей.

Я могу извлечь строку, используя awk, но я не уверен, как я могу сохранить исходный вывод изаменить его на выходе. Ниже я протестировал

cat file.txt | awk -F '|' '{newVar=system("command "$2); print newVar $4}'
#

Пример вывода команды, где мы извлекаем «имя»

openstack show 36a6c06e-5e97-4a53-bb42
+----------------------------+-----------------------------------+
| Property                   | Value                             |
+----------------------------+-----------------------------------+
| id                         | 36a6c06e-5e97-4a53-bb42           |
| name                       | testVM1                           |
+----------------------------+-----------------------------------+

Ответы [ 4 ]

0 голосов
/ 25 октября 2019

Это, наконец, сделал свое дело ..

awk -F' *[|] *' -v OFS=' | ' '{
    cmd = "openstack show \047" $2 "\047"
    while ( (cmd | getline line) > 0 ) {
        if ( line ~ /name/ ) {
            split(line,flds,/ *[|] */)
            $2 = flds[3]
            break
        }
    }
    close(cmd)
    print
}' file
0 голосов
/ 23 октября 2019

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

awk -F ' *| *' '{("command "$2) | getline $2}1' file.txt

например,

$ awk -F ' *| *' '{("date -d @"$2) | getline $2}1' file.txt
test1| Thu 01 Jan 1970 05:50:34 AM IST | test2 | test3

Я изменил разделитель полей с | на *| *, чтобы вместить пространства вокруг полей. Вы можете удалить их на основе вашего фактического ввода.

0 голосов
/ 23 октября 2019

Если command может взять весь список значений один раз и сгенерировать преобразованный список в качестве вывода (например, tr 'a-z' 'A-Z'), тогда вы захотите сделать что-то подобное, чтобы избежать порождения оболочки один раз для каждой строки ввода (чтоочень медленно):

awk -F' *[|] *' '{print $2}' file |
command |
awk -F' *[|] *' -v OFS=' | ' 'NR==FNR{a[FNR]=$0; next} {$2=a[FNR]} 1' - file

в противном случае, если command требуется для вызова с одним значением за раз (например, echo), или вы просто не заботитесь о скорости выполнениятогда вы сделаете:

awk -F' *[|] *' -v OFS=' | ' '{
    cmd = "command \047" $2 "\047"
    if ( (cmd | getline line) > 0 ) {
        $2 = line
    }
    close(cmd)
    print
}' file

\047 s выдаст одинарные кавычки вокруг $2 при передаче на command и защитит его от интерпретации оболочки (см. https://mywiki.wooledge.org/Quotes)и проверка результата getline защитит вас от перезаписи текущих $ 2 без вывода на экран вывода более раннего выполнения команды в случае сбоя (см. http://awk.freeshell.org/AllAboutGetline). close() гарантирует, что вы не завершите работуошибка «слишком много открытых файлов» или другая загадочная проблема, если канал не закрывается должным образом, например, если команда генерирует несколько строк, а вы просто читаете первую.


Учитывая ваш комментарийниже, если вы идете со вторым подходом выше, то вы напишите что-то вроде:

awk -F' *[|] *' -v OFS=' | ' '{
    cmd = "openstack show \047" $2 "\047"
    while ( (cmd | getline line) > 0 ) {
        split(line,flds)
        if ( flds[2] == "name" ) {
            $2 = flds[3]
            break
        }
    }
    close(cmd)
    print
}' file
0 голосов
/ 23 октября 2019

Perl для спасения!

perl -lF'/\|/' -ne 'chomp( $F[1] = qx{ command $F[1] }); print join "|", @F' < file.txt
  • -n читает строку ввода строкой
  • -l удаляет новые строки из ввода и добавляет их к print s
  • F указывает, как разбить каждую входную строку на массив @F
  • $F[1] соответствует второму столбцу, мы заменим его на вывод команды
  • chomp удаляет завершающий символ новой строки из вывода команды
  • join склеивает массив обратно в одну строку
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...