Получите значения раздела файла

Каждый процесс имеет свою собственную среду, скопированную с родителя. Если родитель является оболочкой, существует понятие экспортных переменных, которое нужно рассмотреть, но это не применяется, когда Вы имеете дело с exec() и т.д. непосредственно. LOGNAME переменная обычно устанавливается оболочкой входа в систему, Вы просто видите оставшееся значение, которое не было сброшено. Так, Вы видите дочернюю среду. В некоторых системах Вы не можете легко получить доступ к родителю (или другой процесс) среда, на Linux можно сделать это легко (подвергающийся полномочиям) через /proc)

Можно, вероятно, воспроизвести эффект, который Вы видите путем попытки обоих su и su -, последний инициализирует среду входа в систему оболочки, которая (почти наверняка) сбросит LOGNAME среди других вещей первый оставит это нетронутым.

Используя env команда является одним способом получить чистую среду при запуске нового процесса с командной строки, необходимо проверить execle() документация относительно Вашей системы, чтобы видеть, как сделать что-то подобное.

7
22.08.2014, 16:30
6 ответов

Если у вас есть только 4 строки после [part1] , вы можете используйте параметр -A4 с grep :

cat ${file} | grep -A4 "part1" | cut -d'=' -f2`

В общем случае (более 4 строк после [part1]) используйте sed , чтобы получить текст между двумя частями :

cat ${file} | sed -n "/part1/,/part2/p" | head -n-1

head - это удалить дополнительный part2 в конце

Как terdon сказал, что вам не нужно использовать cat , вы вместо этого можно сделать следующее:

grep -A4 "part1" ${file} | cut -d'=' -f2`

ИЛИ:

sed -n "/part1/,/part2/p" ${file} | head -n-1
8
27.01.2020, 20:15

Нужно использовать более сложный инструмент для разбора файла. Например, awk:

#!/bin/sh 

getCalibDate()
{
 file="${1}"
 value=$(awk  '/\[part/{a++}(a<2 && /Val/){print $NF}' ${file})

    for v in $value
    do
            echo $v
    done
}

getCalibDate ${1}

Здесь переменная a увеличивается каждый раз, когда строка совпадает с [часть . Затем, последнее поле ($NF) выводится, когда строка совпадает с Val, но только если a меньше 2, только если мы находимся в 1-ой секции.

4
27.01.2020, 20:15

Чтобы получить целые строки из первой части:

awk '$1 ~ /^\[/ {n++;next} n==1'

Чтобы просто распечатать правую часть первой =:

awk '$1 ~ /^\[/ {n++;next} n==1 {sub(/^[^=]*=[[:blank:]]*/,""); print}'
2
27.01.2020, 20:15

и используйте следующее:

sed -n -e '/\[part1\]/,/\[part2\]/p' FILE |sed -e '1d;$d'| awk -F "=" '{print $2}'

OUTPUT is:

 a
 val1
 a
 val1
2
27.01.2020, 20:15
sed -n '/part2/q;s/[^=]*=//p' \
<<\DATA
<Title>
 [part1]
  A.File = a
  A.Val = val1
  B.File = a
  B.Val = val1
 [part2]
  A.File = a1
  A.Val = val2
  B.File = a
  B.Val = val1
DATA

OUTPUT

 a
 val1
 a
 val1

Это должно помочь. Он немедленно q uit входной файл, когда впервые встретит строку part2 где-нибудь во входных данных. Это означает, что он даже не пытается прочитать части файла, которые вам не нужны, что должно сделать его очень эффективным.

-n отключает автоматическую печать, поэтому sed печатает только то, что определенно указано в p rint. Единственный раз, когда ему определенно предлагается печатать, это когда он может успешно удалить последовательность из 0 или более символов, не являющихся = , и один символ, который является = .

Если вы хотите вместо этого напечатать всю совпадающую строку, вы можете сделать:

sed -n '/part2/q;/=/p'
0
27.01.2020, 20:15

Здесь есть несколько хороших ответов, но я вижу только один, который включает в себя часть проблемы Val , и неясно, правильно ли это. Я согласен с тем, что awk - «замечательный инструмент», но здесь в нем нет необходимости; Я считаю, что эта команда sed :

sed -n '/\[part1\]/,/\[part2\]/s/.*Val.*=//p' "$file"

, вероятно, делает то, что желает. Как и другие решения sed -e '/ \ [part1 \] /, / \ [part2 \] / p' ( Сетевик и Бэби ), это легко адаптировать для выбора любого раздела. (Вы, конечно, должны знать его имя; если вы знаете только его порядковый номер, вы можете адаптировать ответ Тердона или ответ Гленна Джекмана , оба из которых учитывают разделы, а не ищут конкретное имя.) Если вы не знаете название следующего раздела, вы можете ввести, например,

sed -n '/\[part42\]/,/\[part/s…' "$file"

.

Мой единственный мета-вопрос касается части вопроса cut -d '=' -f2 . Если строка ввода, из которой мы извлекаем данные, содержит несколько = символов после Val (т.е. значение поля содержит = символа (ов)), например,

Einstein.Val = E=mc^2

, то приведенная выше команда cut извлечет только текст между первая и вторая = (т.е. значение поля до (но не включая) первого = ), например, E . Команда sed , которую я представил выше, будет извлекать только текст после последнего = (например, mc ^ 2 ). Чтобы получить все после первого = (например, E = mc ^ 2 ), используйте

sed -n '/\[part1\]/,/\[part2\]/s/.*Val[^=]*=//p' "$file"

Чтобы имитировать поведение разреза (например, E ), используйте

sed -n '/\[part1\]/,/\[part2\]/s/.*Val[^=]*=\([^=]*\).*/\1/p' "$file"

Обратите внимание, что мой подход предполагает, что данные выглядят по крайней мере, в целом как на иллюстрации в вопросе; то есть, по крайней мере, один = появляется где-то справа от строки Val . Соответственно, все мои решения будут игнорировать ввод вроде

Girl.Name = Valerie
Valerie Bertinelli

, даже если он находится между [part1] и [part2] .

2
27.01.2020, 20:15

Теги

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