将变量传递给SED命令

时间:2018-09-11 18:09:04

标签: sed csh

将变量传递给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 :(得分:0)

不幸的是,sed既不了解字段,也不接受变量。为此,您将使用shell或awk或shell或其他语言。 sed S tream ED 监视器,在您的示例中是从stdin而不是变量中获取输入。

如果您确实想将shell变量嵌入sed脚本中,请了解您基本上是在动态创建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 $0 OFS tag}' OFS=, >> path/to/file.csv

AWK是一种更完整的编程语言,并且与sed不同,它支持命名变量。 -v选项可让您预先将awk变量与shell变量的内容一起加载。

CSH is considered harmful有人。我建议您使用POSIX shell,如果这样做只是为了利用大量专家来帮助您解决脚本问题。 :)