How can I print the unescaped version of command line args?
print ARGV[1]
The problem is that you don't want the unescaped command line argument. You want to interpret it. You're passing \t
(the two-character string backslash, lowercase T), and you want that to be translated to a backslash. You'll need to do this manually. Just translating \t
to a tab is easy — gsub(/\\t/, "\t")
— but if you want to support octal escapes as well, and remove backslash before a non-recognized character, that's cumbersome in awk.
split ARGV[1], a, "\\";
s = a[1]; delete a[1];
for (x in a) {
if (skip_next) {
skip_next = 0;
} else if (x == "") {
s = s "\\";
skip_next = 1;
} else if (x ~ /^[0-7][0-7][0-7]/) {
s = s sprintf("%c", 64*substr(x,1,1) + 8*substr(x,2,1) + substr(x,3,1));
sub(/^.../, x);
} else if (x ~ /^[0-7][0-7]/) {
s = s sprintf("%c", 0 + 8*substr(x,1,1) + substr(x,2,1));
sub(/^../, x);
} else if (x ~ /^[0-7]/) {
s = s sprintf("%c", 0 + substr(x,1,1));
sub(/^./, x);
} else {
sub(/^a/, "\a", x) ||
sub(/^b/, "\b", x) ||
sub(/^n/, "\n", x) ||
sub(/^r/, "\r", x) ||
sub(/^t/, "\t", x) ||
sub(/^v/, "\v", x);
}
s = s x;
}
(Warning: untested code!) Instead of this complex code, you could invoke printf
in a subshell. Even that isn't so easy to do when the string could be multiline.
s = ARGV[1]
gsub(/'/, "'\\''", s)
cmd = "printf %b '" s "'."
s = ""
while ((cmd | getline line) > 0) s = s line "\n"
sub(/..$/, "", s)
Note that when you write "\t"
in an awk script, that's a string containing the tab character. It's the way the awk syntax is: backslash has a special meaning in a string literal. Note: in a string literal, not in a string. If a string contains a backslash, that's just another character. The source code snippet "\t"
, consisting of four characters, is an expression whose value is the one-character string containing a tab, in the same way that the source code snippet 2+2
, consisting of three characters, is an expression whose value is the number 4
.
It would be better for your awk script to take the separator argument as a literal string. That would make it easier to use: your interface requires the caller to escape backslashes in the argument. If you want the separator to be a tab, pass an actual tab character.
myscript.awk --sep "$(printf '\t')"
– cuonglm Jun 07 '15 at 17:55