【问题标题】:Passing a Variable to SED Command将变量传递给 SED 命令
【发布时间】:2019-02-16 07:22:36
【问题描述】:

将变量传递给 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.

那么,我应该在sed 命令中将变量$tag 写在哪里?

【问题讨论】:

  • 如果您的问题与列有关,那么awk 可能比sed 更合适。实际上,如果您的问题是关于 CSV,那么 python 值得考虑。
  • 您应该提供一个您尝试过的示例命令,以及该命令的输入和所需的输出。
  • 我已经编辑了我的问题。不幸的是,我不能使用 Python。
  • @mouviciel,如何将变量传递给awk 以使用字段分隔符更新第二列?
  • 你确定这正是你输入的,因为这似乎对我有用。

标签: sed csh


【解决方案1】:

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

如果您确实想在 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 $0 OFS tag}' OFS=, >> path/to/file.csv

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

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

【讨论】:

  • 谢谢你,戈蒂。我使用了awk 而不是sed,它得到了回报。但总的来说,变量无论如何都不能传递给sed,对吧?
  • @KarimElsabry - 对,sed 不使用变量(除非您将“保持空间”视为变量),因此它没有将外部数据加载到不存在数据中的机制类型。进入 sed 的所有内容要么从文件中读取,要么从标准输入中读取。