如何在 shell 脚本中转义符号?

如何在 shell 脚本中转义符号?

我想使用 shell 脚本将文本写入其他文件echo,但数据并未按照我预期的格式写入

echo paste B01_reprojected_subset_comma_updated.csv  B02_reprojected_subset_comma_updated.csv B03_reprojected_subset_comma_updated.csv B04_reprojected_subset_comma_updated.csv B05_reprojected_subset_comma_updated.csv B06_reprojected_subset_comma_updated.csv B07_reprojected_subset_comma_updated.csv B08_reprojected_subset_comma_updated.csv B8A_reprojected_subset_comma_updated.csv B09_reprojected_subset_comma_updated.csv B10_reprojected_subset_comma_updated.csv B11_reprojected_subset_comma_updated.csv B12_reprojected_subset_comma_updated.csv |awk -F",||\t" '{print  $1","$2","$3","$6","$9","$12","$15","$18","$21","$24","$27","$30","$33","$36","$39}'>allbands.csv >> jobstext.sh

但是我在 jobstext.sh 中收到了这样的文本

paste B01_reprojected_subset_comma_updated.csv B02_reprojected_subset_comma_updated.csv B03_reprojected_subset_comma_updated.csv B04_reprojected_subset_comma_updated.csv B05_reprojected_subset_comma_updated.csv B06_reprojected_subset_comma_updated.csv B07_reprojected_subset_comma_updated.csv B08_reprojected_subset_comma_updated.csv B8A_reprojected_subset_comma_updated.csv B09_reprojected_subset_comma_updated.csv B10_reprojected_subset_comma_updated.csv B11_reprojected_subset_comma_updated.csv B12_reprojected_subset_comma_updated.csv,,,,,,,,,,,,,,

我试图转义特殊符号,但数据仍然不是正确的格式。

有人可以帮我做到这一点吗?

paste B01_reprojected_subset_comma_updated.csv B02_reprojected_subset_comma_updated.csv B03_reprojected_subset_comma_updated.csv B04_reprojected_subset_comma_updated.csv B05_reprojected_subset_comma_updated.csv B06_reprojected_subset_comma_updated.csv B07_reprojected_subset_comma_updated.csv B08_reprojected_subset_comma_updated.csv B8A_reprojected_subset_comma_updated.csv B09_reprojected_subset_comma_updated.csv B10_reprojected_subset_comma_updated.csv B11_reprojected_subset_comma_updated.csv B12_reprojected_subset_comma_updated.csv |awk -F",||\t" '{print  $1","$2","$3","$6","$9","$12","$15","$18","$21","$24","$27","$30","$33","$36","$39}'>allbands1.csv

答案1

为了防止 shell 接触您的文本(包括特殊字符,如$>或)*,请将所有内容放在单引号中。要在字符串中包含单引号,您必须中断引用的字符串并添加反斜杠转义的单引号,结果如下'here comes the embedded '\''quote'

echo 'paste B01_reprojected_subset_comma_updated.csv  B02_reprojected_subset_comma_updated.csv B03_reprojected_subset_comma_updated.csv B04_reprojected_subset_comma_updated.csv B05_reprojected_subset_comma_updated.csv B06_reprojected_subset_comma_updated.csv B07_reprojected_subset_comma_updated.csv B08_reprojected_subset_comma_updated.csv B8A_reprojected_subset_comma_updated.csv B09_reprojected_subset_comma_updated.csv B10_reprojected_subset_comma_updated.csv B11_reprojected_subset_comma_updated.csv B12_reprojected_subset_comma_updated.csv |awk -F",||\t" '\''{print  $1","$2","$3","$6","$9","$12","$15","$18","$21","$24","$27","$30","$33","$36","$39}'\''>allbands.csv' >> jobstext.sh

答案2

如果拆分打印并使用printf格式字符串来排列输出,会更容易。首先,粘贴命令利用括号扩展:

printf "%s " paste B{01..12}_reprojected_subset_comma_updated.csv >> jobstext.sh

然后,使用 OFS 简化的 awk 命令:

printf "| %s '%s' %s %s '%s' > %s\n" awk -F',|\t' -v OFS=, '{print $1, $2, $3, $6, $9, $12, $15, $18, $21, $24, $27, $30, $33, $36, $39}' allbands1.csv >> jobstext.sh

您还可以使用%q来简化所使用的格式字符串printf

答案3

如果没有文件样本或对要执行的操作或输出文件所需格式的清晰描述,那么这仅仅是猜测。也许您想将命令行(粘贴内容|awk 操作)附加到文件 jobstext.sh。最好使用编辑器来避免嵌套引用问题...

但是您的问题询问了如何转义特殊字符,因此回答该问题的一个选项是将单引号括在双引号内。将较长的文件名缩写为 B01 等,如下所示。

echo 'paste B01 B02 B03 B04 B05 B06 B07 B08 B8A B09 B10 B11 B12 |
awk -F",||\t" '"'"'{print "$1","$2","$3","$6","$9","$12","$15","$18","$21",
"$24","$27","$30","$33","$36","$39}'"'"' >allbands.csv' >> jobstext.sh

第一个单引号启动一个字符串,该字符串包含粘贴命令、文件名、管道、awk 和 F 选项。然后,序列中的第一个单引号'"'"'关闭字符串,接下来的 3 个字符定义另一个单引号字符串,最后一个字符是启动第三个字符串(包括括号中的 awk 操作)的单引号。类似的 5 个引号序列关闭该字符串,插入另一个单引号,并启动第五个字符串(包括将输出重定向到 allbands.csv)。最后,该字符串关闭(用该行的最后一个引号),因此所有 5 个字符串都连接起来并附加到 jobstext.sh。

这很麻烦,但这就是试图在一个命令行上使用两级单引号的结果。单引号是必需的,以防止 awk 语句被 shell 解释。

改进措施包括 1/ 使用可以扩展的文件名*(但您的“B8A”引入了不一致,阻止了简单的文件名扩展),以及 2/ 通过将其编辑到 jobstext.sh 中来简化命令。@muru 的回答中的建议值得采纳(但要小心那个“B8A”文件!)

相关内容