如何在AWK脚本中使用空格对shell变量进行转义

时间:2018-11-29 22:06:23

标签: bash awk escaping

我将“ file1 Nov 2018.txt”的路径存储在变量“ var”中。然后我在awk脚本中使用这个shell变量 生成另一个脚本(这是一个小示例)。问题是路径和文件名包含空格,甚至我也将变量放在双引号“”之间 在awk中,我在单引号之间插入了”也不起作用。我收到错误消息“没有这样的文件或目录”

如何处理带有空格的路径?

脚本如下:

var="/mydrive/d/data 2018/Documents Nov/file1 Nov 2018.txt"
z=$(awk -v a="$var" 'BEGIN{str = "cat " 'a' ; print str}')
eval "$z"

我得到这些错误:

$ eval "$z"
cat: /mydrive/d/data: No such file or directory
cat: 2018/Documents: No such file or directory
cat: Nov/file1: No such file or directory
cat: Nov: No such file or directory
cat: 2018.txt: No such file or directory

感谢您的帮助。

4 个答案:

答案 0 :(得分:5)

单引号转义序列在这里派上用场。请注意,047是ASCII const bodyFormData = new FormData(); if (typeof this.image !== 'string') { bodyFormData.append('attached_file', this.image); bodyFormData.append('descriptionImage', this.descriptionImage); } this.axios.post('/api/', bodyFormData, { headers: { 'Content-Type': 'multipart/form-data' } }) .then((response) => { this.isSending = false; this.$snackbar.open(response.data.results); this.feedback = {}; this.image = {}; }).catch((err) => { this.$snackbar.open({ message: err.response.data.error, type: 'is-danger' }); this.isSending = false; }); 字符的八进制值,而awk允许您在字符串中使用'以使用其八进制值包含任何字符。

\nnn

使用$ cat 'foo bar.txt' a b c 1 2 3 $ var="foo bar.txt" $ echo "$var" foo bar.txt $ z=$(awk -v a="$var" 'BEGIN{print "cat \047" a "\047"}') $ eval "$z" a b c 1 2 3 可能会更好一些:

printf

问题来自于单引号对shell具有特殊含义的事实,因此当awk程序在命令行上也使用单引号时,就会出现冲突就不足为奇了。

可以通过将awk程序放在其自己的文件中来避免这种情况:

$ awk -v a="$var" 'BEGIN{ printf "cat \047%s\047\n", a }'
cat 'foo bar.txt'

答案 1 :(得分:1)

删除a周围的单引号,并添加转义的双引号。

$ echo success > "a b"
$ var="a b"; z=$(awk -v a="$var" 'BEGIN{print "cat \"" a "\""}');
$ eval "${z}"

success

但是,很可能您正在执行某些不必要的复杂任务。

答案 2 :(得分:1)

$ cat > path\ to/test
foo
$ z=$(awk -v a="$var" 'BEGIN{gsub(/ /,"\\ ",a); str = "cat " a ; print str}')   
$ echo "$z"
cat path\ to/test
$ eval "$z"
foo

(在此解决方案中)密钥为:gsub(/ /,"\\ ",a),即。使用\(由于awk,\\)转义空格。

答案 3 :(得分:1)

使用bash的printf %q "$var",您可以正确地转义任何字符串以供以后在eval中使用-甚至可以正确处理换行符。但是,结果字符串可能包含特殊符号,例如\,当使用awk分配变量时,它们可以由awk -v var="$var"解释。因此,最好通过stdin传递变量:

path='/path/with spaces/and/special/symbols/like/*/?/\/...'
cmd=$(printf %q "$path" | awk '{print "cat "$0}')
eval "$cmd"

在此示例中,生成的命令$cmd

cat /path/with\ spaces/and/special/symbols/like/\*/\?/\\/...