Передача переменной в команду SED - PullRequest
0 голосов
/ 11 сентября 2018

Каков синтаксис для передачи переменной в команду sed, которая обновляет второй столбец в файле CSV.Имя переменной $tag Это команда, которую я использовал, но я не знаю, куда именно поместить переменную.

   basename "$dec" | sed 's/.*/&,A/' >> home/kelsabry/Downloads/Tests/results.csv 

, где $dec - это переменная, которая возвращает мне определенный каталог.

Вывод:

Downloads, A
Documents, A
etc.

Моя команда передать переменную в sed для обновления второго столбца была:

   basename "$dec" | sed 's/.*/&,'$tag'/' >> home/kelsabry/Downloads/Tests/results.csv 

, но она выдала мне такой вывод:

Downloads, '$tag'
Documents, '$tag'
etc.

Итак, куда мне записать переменную $tag в команде sed?

1 Ответ

0 голосов
/ 16 сентября 2018

К сожалению, sed не знает ни полей, ни способен принимать переменные. Для этого вы должны использовать shell или awk, shell или какой-либо другой язык. sed это S tream ED итор, и в вашем примере он принимает входные данные из stdin, а не из переменной.

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

Например, если существует вероятность того, что ваша переменная $tag может содержать что-то, что приведет к неправильной интерпретации сценария sed (т. Е. Возможно, это произошло из-за пользовательского ввода), тебе нужна защита В оболочке POSIX возможно что-то вроде этого:

if [ "$tag" != "${tag#*[!A-Z]}" ]; then
  printf 'ERROR: invalid tag\n' >&2
  exit 1
fi

или даже:

case "$tag" in
  [A-Z]) : ;;
  *) printf 'ERROR: invalid tag\n' >&2; exit 1 ;;
esac

тогда

# Note the alternative to `basename`
echo "${dec##*/}" | sed 's/$/,'"$tag"'/' >> path/to/file.csv

Обратите внимание, что sed ничего не знает о полях или CSV. sed просто используется для добавления строки в конец строки.

Конечно, в csh (который, возможно, не следует использовать для автоматизации сценариев) вам не хватает более полезных инструментов расширения параметров, но вы все равно можете защитить себя другими способами:

if ( $%tag == 1 ) then
  switch ($tag)
    case [A-Z]:
      printf '%s,%s\n' `basename "$dec"` "$tag"
      breaksw
    default:
      printf 'ERROR: invalid tag\n'
      exit 1
      breaksw
  endsw
else
  printf 'ERROR: invalid tag\n'
  exit 1
endif

(Примечание: это не проверено. Пробег зависит от нескольких условий. Может содержать орехи.)

Проблема, которую вы указали в своем вопросе, была связана с цитированием. Вы сказали: sed 's/.*/&,'$tag'/' >. Альтернативой может быть использование awk:

echo "${dec##*/}" | awk -v tag="$tag" '{print $0 OFS tag}' OFS=, >> path/to/file.csv

Awk является более полным языком программирования и поддерживает именованные переменные, в отличие от sed. Опция -v позволяет предварительно загрузить переменную awk с содержимым переменной оболочки.

CSH считается вредным для некоторых. Я бы порекомендовал делать это в оболочке POSIX, хотя бы только для того, чтобы воспользоваться преимуществами гораздо большего числа экспертов, которые могут помочь с вашими вопросами сценариев. :)

...