Косвенный доступ к переменной среды [дубликат]

Lo más simple que viene a la mente es dividir las líneas en comas e insertar comas adicionales donde solo hay dos. La limitación obvia es que si tiene comas en los valores reales, esto se romperá.

$ cat test.csv | sed -r 's/^([^,]*),([^,]*),([^,]*)$/\1,\2,,\3, /g'
"var1", "var2", "var3", "var4", "var5"
"2001", "yellow", "123", "abc", "bcdefg"
"2002", "yellow", "123", "abw", "asdfkl"
"2001", "green",, "abe", 
"2002", "green",, "abp", 
"2001", "blue", "324", "abx", "badsf"
"2002", "blue", "231", "abl", "cpq"

Para algo más general, probablemente escribiría un script de Python (que tiene capacidades CSV integradas -en ). Por ejemplo, esto lee los CSV de stdin y los envía a stdout:

#!/usr/bin/env python
import sys
import csv

missing = [3, 5]  # 1-indexed positions of missing values
missing.sort()  # enforce the increasing order
reader = csv.reader(sys.stdin, delimiter=',', skipinitialspace=True)
writer = csv.writer(sys.stdout)
header = next(reader)  # get first row (header)
writer.writerow(header)  # write it back
for row in reader:
    if len(row) < len(header):
        # row shorter than header -> insert empty strings
        # inserting changes indices so `missing` must be sorted
        for idx in missing:
            row.insert(idx - 1, '')
    writer.writerow(row)

El beneficio de usar un analizador CSV real es que maneja correctamente comas o comillas en valores y otros casos extremos. El formato de salida también será un CSV correcto, pero un poco diferente al que tenía:

$ cat test.csv | python test.py 
var1,var2,var3,var4,var5
2001,yellow,123,abc,bcdefg
2002,yellow,123,abw,asdfkl
2001,green,,abe,
2002,green,,abp,
2001,blue,324,abx,badsf
2002,blue,231,abl,cpq

Como puede ver, no hay comillas ni espacios superfluos después de las comas. Si realmente los necesita, puedo considerar la configuración del dialecto CSV para el escritor.

4
01.03.2019, 19:28
3 ответа

С помощью косвенного расширения (, также иногда называемого «переменной косвенностью» ),

ev=USER
printf '%s\n' "${!ev}"

Это описано в руководствеbash(5.0 )в разделе «Расширение параметров».

Или, сделав evссылку на имя, (требует bash4.3+ ),

declare -n ev=USER
printf '%s\n' "$ev"

Это описано в руководствеbash(5.0 ), как раз перед разделом «Позиционные параметры».

11
27.01.2020, 20:46

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

printenv -- "$ev"

Для переменных оболочки с любой оболочкой, подобной Bourne -, вы можете:

eval 'printf "%s\n" "${'"$ev"}'}"'

Или сzsh:

printf '%s\n' "${(P)ev}"

Или сbash:

printf '%s\n' "${!ev}"

Все 3 уязвимости являются уязвимостями внедрения произвольных команд, если содержимое $evне находится под вашим контролем.

5
27.01.2020, 20:46

Вы также можете оценить команду после замены значения для $ev:

eval echo "$"$ev

Часть "$"$evпреобразуется в $USER, поэтому evalвыполняет echo $USER.

2
27.01.2020, 20:46

Теги

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