首页 > 解决方案 > 通过 sed 将文本附加到脚本中

问题描述

我正在尝试通过 bash 脚本(& sed)调用目录数组的元素,但它会中断:

sed: -e expression #1, char 33: unknown option to `s'

#!/bin/bash


directory=(one two three)


for m in "${directory[@]}"
do
  echo "${m}" ;

sed -i -e '45 s/$/\napiVersion: extensions/v1beta1\nkind: Ingress\nmetadata:\n  namespace: ${m}\n  name: ${m}-api1-ingress\n  annotations:\n    nginx.ingress.kubernetes.io/use-regex: "true"\n    nginx.ingress.kubernetes.io/configuration-snippet: |\n      rewrite "(?i)/${m}/api1/(.*)" /$1 break;\n      rewrite "(?i)/${m}/api1$" / break;\n  labels:\n    Name: ${m}\n    App: test-api\n    Tier: end\nspec:\n  rules:\n  - host: www.test.com\n    http:\n      paths:\n      - backend:\n          serviceName: ${m}-test-api-1\n          servicePort: 80\n        path: /${m}/api1\n\n---\n\napiVersion: extensions/v1beta1\nkind: Ingress\nmetadata:\n  namespace: ${m}\n  name: ${m}-api2-ingress\n  annotations:\n    nginx.ingress.kubernetes.io/use-regex: "true"\n    nginx.ingress.kubernetes.io/configuration-snippet: |\n      rewrite "(?i)/${m}/api2/(.*)" /$1 break;\n      rewrite "(?i)/${m}/api2$" / break;\n  labels:\n    Name: ${m}\n    App: test-api\n    Tier: end\nspec:\n  rules:\n  - host: www.test.com\n    http:\n      paths:\n      - backend:\n          serviceName: ${m}-test-api-2\n          servicePort: 80\n        path: /${m}/api2/g' /home/test/*.yaml;

done

标签: arraysbashkubernetes

解决方案


您应该能够使用以下内容:

sed -i -e "45 a\
apiVersion: extensions/v1beta1\n\
kind: Ingress\n\
metadata:\n\
  namespace: ${m}\n\
  name: ${m}-api1-ingress\n\
  annotations:\n\
    nginx.ingress.kubernetes.io/use-regex: \"true\"\n\
    nginx.ingress.kubernetes.io/configuration-snippet: |\n\
      rewrite \"(?i)/${m}/api1/(.*)\" /\$1 break;\n\
      rewrite \"(?i)/${m}/api1$\" / break;\n\
  labels:\n\
    Name: ${m}\n\
    App: test-api\n\
    Tier: end\nspec:\n\
  rules:\n\
  - host: www.test.com\n\
    http:\n\
      paths:\n\
      - backend:\n\
          serviceName: ${m}-test-api-1\n\
          servicePort: 80\n\
        path: /${m}/api1\n\
\n\
---\n\
\n\
apiVersion: extensions/v1beta1\n\
kind: Ingress\nmetadata:\n\
  namespace: ${m}\n\
  name: ${m}-api2-ingress\n\
  annotations:\n\
    nginx.ingress.kubernetes.io/use-regex: \"true\"\n\
    nginx.ingress.kubernetes.io/configuration-snippet: |\n\
      rewrite \"(?i)/${m}/api2/(.*)\" /\$1 break;\n\
      rewrite \"(?i)/${m}/api2$\" / break;\n\
  labels:\n\
    Name: ${m}\n\
    App: test-api\n\
    Tier: end\n\
spec:\n\
  rules:\n\
  - host: www.test.com\n\
    http:\n\
      paths:\n\
      - backend:\n\
          serviceName: ${m}-test-api-2\n\
          servicePort: 80\n\
        path: /${m}/api2" \
/home/test/*.yaml

\n\注意以: the结尾的每一行\n用于sed添加换行符,而 the\用于转义后面的换行符并将其bash解析为装饰性并避免将其传递给sed将其视为append 命令的结尾的行。

另请注意,需要转义数据中的双引号,以免它们被视为关闭包含整个数据的引号。

鉴于数据量和动态生成数据的存在,最好将通用数据存储在其自己的文件中,对该文件进行第一次传递以将变量替换为它们的值,然后使用sedor other 插入整个转换后的文件(w filename带有 的命令sed)。这样,您就不必费心处理数据包含的每个可能被解析为元字符的字符,因为文件中的数据将自动被解析为数据。


推荐阅读