将变量传递给 SED 命令

Passing a Variable to SED Command

将变量传递给更新 CSV 文件中第二列的 sed 命令的语法是什么。变量名称是 $tag 这是我用过的命令,但我不知道把变量放在哪里。

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

其中 $dec 是变量,returns 对我来说是某个目录。

输出:

Downloads, A
Documents, A
etc.

我将变量传递给 sed 以更新第二列的命令是:

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

但它给了我这个输出:

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

那么,sed命令中的变量$tag应该写在什么地方呢?

不幸的是,sed 既不知道字段也不能接受变量。为此,您将使用 shell 或 awk 或 shell 或其他语言。 sed 是一个 Stream EDitor 在你的例子中是从 stdin 获取输入,而不是变量。

如果您确实想在 sed 脚本中嵌入 shell 变量,请理解您基本上是在即时创建 sed 脚本,确保安全地执行此操作很重要。

例如,如果您的 $tag 变量可能包含会导致对 sed 脚本的误解的内容(即它可能来自用户输入), 你需要保护。在 POSIX shell 中,可能是这样的:

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 [=14=] OFS tag}' OFS=, >> path/to/file.csv

Awk 是一种更完整的编程语言,并且支持命名变量,这与 sed 不同。 -v 选项允许您使用 shell 变量的内容预加载 awk 变量。

CSH is considered harmful 一些。我建议改为在 POSIX shell 中执行此操作,如果只是为了利用可以帮助您解决脚本编写问题的大量专家的话。 :)