Создание списка без запятой - PullRequest
1 голос
/ 27 января 2020

В настоящее время я использую следующую команду для экспорта переменной среды FOO:

export FOO=$(for i in {0..7}; do echo -n "uops_dispatched_port.port_$i|p$i,"; done)

В результате получается строка:

uops_dispatched_port.port_0|p0,uops_dispatched_port.port_1|p1,uops_dispatched_port.port_2|p2,uops_dispatched_port.port_3|p3,uops_dispatched_port.port_4|p4,uops_dispatched_port.port_5|p5,uops_dispatched_port.port_6|p6,uops_dispatched_port.port_7|p7,

Мне бы хотелось, чтобы аналогично просто, DRY, команда, которая приводит к той же строке без запятой.

Ответы [ 8 ]

2 голосов
/ 27 января 2020

Я тоже!

export FOO=$(seq 0 7 | xargs -I{} echo "uops_dispatched_port.port_{}|p{}" | paste -sd,)
  • seq генерирует числа от 0 до 7
  • xargs -I{} выводит число в запрошенном странном формате.
  • paste -sd, соединяет строки запятой.
2 голосов
/ 27 января 2020

Вы можете использовать расширение параметра, чтобы удалить запятую, например .:

foo=$(for i in {0..7}; do echo -n "uops_dispatched_port.port_$i|p$i,"; done)
export FOO=${foo%,}

Ниже приведен фрагмент из Bash руководства , описывающего эту конструкцию:

$ {параметр% word}
$ {параметр %% word}

Слово расширяется для создания шаблона и сопоставляется в соответствии с правилами, описанными ниже (см. Шаблон Matching ). Если шаблон соответствует завершающей части расширенного значения параметра, то результатом расширения является значение параметра с самым коротким совпадающим шаблоном (случай «%») или самым длинным совпадающим шаблоном (случай «%%») удален. Если параметр равен «@» или «*», операция удаления шаблона применяется к каждому позиционному параметру по очереди, и расширение является результирующим списком. Если параметром является переменная массива, подписанная с помощью «@» или «*», операция удаления шаблона применяется к каждому члену массива по очереди, и расширение является результирующим списком.

1 голос
/ 27 января 2020

Не могли бы вы попробовать следующее:

export FOO=$(a=(); for i in {0..7}; do a+=("uops_dispatched_port.port_$i|p$i"); done; IFS=,; echo "${a[*]}")

Назначение IFS ограничено внутри подоболочки и не влияет на следующие утверждения.

1 голос
/ 27 января 2020

Вы можете передать вывод for-l oop на head -c-1, чтобы удалить запятую:

export FOO=$(for i in {0..7}; do echo -n "uops_dispatched_port.port_$i|p$i,"; done | head -c-1)
0 голосов
/ 27 января 2020

Также вы можете пометить его как последний и точно удалить

export FOO=$(for i in {0..7}; do echo -n "uops_dispatched_port.port_$i|p$i,"; done; printf "_LAST_")
echo ${FOO//,_LAST_/}
0 голосов
/ 27 января 2020

Вместо того, чтобы печатать запятую в конце каждой строки echo (и затем удалять последнюю), выведите запятую в начале строки echo для 2-го и 7-го проходов через l oop ...

  • удалить запятую (,) из echo команда
  • установить переменную dl="" для первого прохода через l oop
  • print ${dl} в начале echo строка
  • установить dl="," в конце l oop так, чтобы ...
  • при последовательных проходах через l oop the echo строка начинается с запятой (,)

Это дает нам:

$ export FOO=$(dl="" ; for i in {0..7}; do echo -n "${dl}uops_dispatched_port.port_$i|p$i"; dl=","; done)
$ echo $FOO
uops_dispatched_port.port_0|p0,uops_dispatched_port.port_1|p1,uops_dispatched_port.port_2|p2,uops_dispatched_port.port_3|p3,uops_dispatched_port.port_4|p4,uops_dispatched_port.port_5|p5,uops_dispatched_port.port_6|p6,uops_dispatched_port.port_7|p7

ПРИМЕЧАНИЕ : я только что заметил, что это тот же лог c Кент использует в своем ответе; Я решил использовать жестко заданные присвоения переменной dl, а не условный тест, который использует Кент; одинаковые логики c (разные реализации) и одинаковые результаты ...

0 голосов
/ 27 января 2020

Еще один использует read и PE непосредственно внутри подстановки команд.

export foo=$(read -r var < <(for i in {0..7}; do printf '%s' "uops_dispatched_port.port_$i|p$i,"; done); printf '%s' "${var%,}" )

Или использовать канал доброй линии с группировкой команд с использованием фигурных скобок { }

export foo=$(for i in {0..7}; do printf '%s' "uops_dispatched_port.port_$i|p$i,"; done | { read -r var ; printf '%s' "${var%,}" ; } )
0 голосов
/ 27 января 2020

Попробуйте:

export foo=$(awk 'BEGIN{for(i=1;i<=7;i++)printf "%suops_dispatched_port.port_%d|p%d",(i>1?",":""),i,i}')
...