我花了一整天的时间尝试处理一些带有反斜杠和名字空格的文件。无论我做什么,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说了一些关于一些未终止的正则表达式的废话。
有什么想法吗?谢谢!
答案 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}'