awk处理包含反斜杠疯狂的文件名

时间:2011-12-11 10:55:14

标签: awk filenames backslash

我花了一整天的时间尝试处理一些带有反斜杠和名字空格的文件。无论我做什么,awk(gawk)拒绝打印反斜杠:

echo "this/pathname/contains/spa ces/and/back\\slashes" | xargs -d'\n' -n1 -I{} bash -c 'echo "{}"; echo whatever | gawk "{printf {}}"'
this/pathname/contains/spa ces/and/back\slashes
gawk: {printf this/pathname/contains/spa ces/and/back\slashes}
gawk:                                           ^ syntax error
gawk: {printf this/pathname/contains/spa ces/and/back\slashes}
gawk:                                                ^ backslash not last character on line

由于退格直接进入awk代码,因此无效。

echo "this/pathname/contains/spa ces/and/back\\slashes" | xargs -d'\n' -n1 -I{} bash -c 'echo "{}"; echo whatever | gawk "{printf \"{}\"}"'
this/pathname/contains/spa ces/and/back\slashes
gawk: warning: escape sequence `\s' treated as plain `s'
this/pathname/contains/spa ces/and/backslashes

这很有效,但awk吃了反斜杠。如上所示,echo打印它,但awk不打印。

echo "this/pathname/contains/spa ces/and/back\\slashes" | ./escape.sh | xargs -d'\n' -n1 -I{} bash -c 'echo "{}"; echo whatever | gawk "{printf \"{}\"}"'
this/pathname/contains/spa\ ces/and/back\slashes
gawk: warning: escape sequence `\ ' treated as plain ` '
gawk: warning: escape sequence `\s' treated as plain `s'

接下来,我尝试使用escape.sh

转义文件名
#!/bin/bash
xargs -d'\n' -n1 -I{} bash -c 'echo $(printf "%q" "{}")'

现在有一个双反斜杠,但awk仍抱怨。

echo "this/pathname/contains/spa ces/and/back\\slashes" | ./escape.sh | xargs -d'\n' -n1 -I{} bash -c 'echo "{}"; echo whatever | gawk -v VAR=$(printf "%q" "{}") "{printf VAR}"'
this/pathname/contains/spa\ ces/and/back\slashes
gawk: ces/and/back\\slashes
gawk:        ^ syntax error
gawk: ces/and/back\\slashes
gawk:         ^ unterminated regexp

现在awk说了一些关于一些未终止的正则表达式的废话。

有什么想法吗?谢谢!

3 个答案:

答案 0 :(得分:1)

您正在解决错误的问题:无论使用哪种工具,UNIX-Systems上的文件名中的反斜杠和空格都将意味着额外的工作。在我看来,你应该清理文件名,然后处理它们。

尝试:

sed "s/ /_/g;s/\\\\/-/g"

HTH Chris

答案 1 :(得分:1)

修复只是将输入到mawk的每个反斜杠加倍,无论是在输入中还是通过变量。 像这样:

# awk needs escaped backslashes
VAR=$(echo "$1" | sed -r 's:\\:\\\\:g')

mawk -v VAR="$VAR" -f "script.awk"

因此,如果在$ 1内传递包含反斜杠的文件名,则可以获得预期结果。

答案 2 :(得分:0)

我不明白你为什么要管道进入xargs。这是您的流程的要求吗?你能做这样的事吗:

filename='this/pathname/contains/spa ces/and/back\slashes'
awk -v "fname=$filename" 'BEGIN {print fname}'