9

So, basically, I want to successfully pass an arbitrary string in java that could contain special characters (such as tabs). Here's this code sample:

String tab = "\t"; 
//String tab = args[0];
String full = "hi"+tab+"hi"+tab+"bye";
String[] parts = full.split(tab);
String print = "";
for (String s : parts) {
    print += s + tab;
}
print = print.substring(0, print.length()-tab.length());
System.out.println(print);

Split successfully recovers the parts regardless of how the variable tab is defined. However, when it's actually printed, defining tab manually (the non-commented out version) prints it as expected, with tab characters. However, passing through command line causes it to actually print "\t" (the same as if the String was actually "\\t" for instance).

I'm primarily using bash, and would be happy for any bash-specific ideas, though would be happier if it also included a general explanation of what's happening. Why is the regex of both the same while the String literal is different?

bash invocation of the program:

ARGS="$X $Y $Z \t"

java -cp $CLASSPATH $MEM $PROGRAM $ARGS 2> "${PROGRAM##*.}-error.log" > "${PROGRAM##*.}-out.log"

The answer provided here does actually mostly work for my purposes, is fairly readable, and generally only fails on fairly unusual things: "\\\t", for instance: https://gist.github.com/uklimaschewski/6741769

6
  • I dont get your question. You want that your java code calls another program and passes "real" tabs to that? Commented Oct 31, 2016 at 8:07
  • maybe you should post how you executed this java code in bash Commented Oct 31, 2016 at 8:08
  • @bhaal can you add a sample invocation from the command line that you use? Commented Oct 31, 2016 at 8:20
  • ok, I added the actual invocation. Commented Oct 31, 2016 at 17:43
  • 1
    This isn't even vaguely a duplicate of the indicated question. Commented Oct 31, 2016 at 22:15

4 Answers 4

7

The tab that you defined in code is a single-character string (since "\t" is an escape sequence). From the command line you get a two-characters string, as bash doesn't handle "\t" as the tab character.

To pass that from command line, you can use echo -e which supports escape sequences like \t (or \n and a few others):

$ java Main "$(echo -en '\t')"
Sign up to request clarification or add additional context in comments.

2 Comments

In Bash, you can do that more elegantly with C-string syntax; java Main $"\t"
java did not seem to capture the argument for the one in the answer. For the second, java captures the bash argument as a string literal
4

The simplest by far is:

java my.package.Main $'\t'

3 Comments

this actually passes that as a string literal, and doesn't split correctly
@bhaall $ echo -n $'\t' | od -x 0000000 0009
This works for me from the command line
2

If you pass '\t' or "\t" on your command line, it causes a literal backslash followed by a t to be passed to your command:

$ echo -n '\t' | xxd
00000000: 5c74                                     \t

$ echo -n "\t" | xxd
00000000: 5c74                                     \t

You can type a tab on your command line using Ctrl-v then Tab:

$ echo -n '     ' | xxd
00000000: 09                                       .

(That wide space is a tab character, not lots of spaces).

1 Comment

I tried typing a literal tab, and java didn't seem to capture it as an argument. I'm maybe not entirely sure what you're suggesting
2

To pass a tab as an argument from bash, you can do any of the following:

mycommand $'arg\tcontaining\ttabs'
Which works because $'' in bash interprets escape sequences.

mycommand 'argctrl-vtabcontainingctrl-vtabtabs'
Which works because ctrl-v causes the next character typed to be inserted literally rather than being interpreted.

mycommand "$(printf 'arg\tcontaining\ttabs')"
Which works, in bash and other shells, because printf interprets backslash-escaped characters in its first argument.

2 Comments

I tried that, but java captured it as a string literal and did not split on it correctly
Are you certain you are using bash and not something like dash? Did the printf version work for you?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.