12

what would be an opposite of split() in awk? Imagine I have array containig characters/integers.

What I've tried:

color = "#FFFF00";
printf("color original: %s\n", color);
split(color, chars, "");
joined = "";
for (i=1; i <= length(chars); i++) {
    joined = joined + chars[i];
}
printf("color joined: %s\n", joined);

however the output is:

color original: #FFFF00
color joined: 0

that is of course incorrect.

UPDATE: cool, ended up with the following code (inspired by join function present in answers):

color = "#FFFF00";
printf("color original: %s\n", color);
split(color, chars, "");
joined = "";
for (i=1; i <= length(chars); i++) {
    joined = joined "" chars[i];
}
printf("color joined: %s\n", joined);

the trick was not to use + sign when joining things back

Peter Butkovic
  • 11,143
  • 10
  • 57
  • 81
  • 1
    A few things: the `""` in `joined "" chars[i]` above isn't doing anything. Although the approach above will work for single characters in an array, it is not the way to do this in general. Using length() on an array like that is GNU-awk specific. Get rid of the null statements (trailing semi-colons). printf is a builtin with a synopsis of `printf fmt,data`, not a function so printf(stuff) does NOT do what you think it does. I'll post something simple that does what you want but in the general case. – Ed Morton Nov 30 '12 at 15:49

5 Answers5

17

Here's a solution that doesn't rely on gawk or knowing the length of the array and lets you put a separator (space in this case) string between each array element if you like:

color = "#FFFF00"
printf "color original: %s\n", color
split(color, chars, "")
joined = sep = ""
for (i=1; i in chars; i++) {
    joined = joined sep chars[i]
    sep = " "     # populate sep here with whatever string you want between elements
}
printf "color joined: %s\n", joined

I also cleaned up the incorrect use of printf and the spurious semi-colons.

In the above script split(color, chars, "") relies on having a version of awk that will split a string into an array given a null field separator, which is undefined behavior per POSIX, but that's not what this answer is about - the question is how to join array elements not how to split them.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
1

Here is a way with POSIX Awk:

br = "red,orange,yellow,green,blue"
ch = split(br, de, ",")
print "original: " br
printf "joined: "
for (ec in de) printf ec == ch ? de[ec] "\n" : de[ec] "-"

Output:

original: red,orange,yellow,green,blue
joined: red-orange-yellow-green-blue
  • 1
    For me, in FreeBSD's awk, this (1) requires parentheses around the inline conditional in the last line, and (2) prints the first field after a newline. I think the failure is because awk doesn't guarantee that array elements will be processed in order. Use `for(i=1;i<=ch;i++)` instead. – ghoti Oct 06 '16 at 08:58
  • That will shuffle the order of the elements as @ghoti points out, can fail with a syntax error in some awks due to no parens around the ternary, and would fail if the strings being joined contained printf formatting chars like `%` as it's doing `printf data` instead of `printf "%s", data`. – Ed Morton Jan 24 '22 at 12:00
0

What you want (in your loop) is string concatenation.

Sjoerd
  • 74,049
  • 16
  • 131
  • 175
  • correct, however I wasn't able to udpate my code to use it somehow, as I don't want to print directly but rather keep result in joined valiable – Peter Butkovic Nov 30 '12 at 09:05
0

Similar to previous answers and less elegant, but easy and short:

color = "#FFFF00"
printf "color original: %s\n", color
split(color, chars, "")
for (i=1; i<=length(chars); i++) {
    (i==1) ? joined = chars[i] : joined = joined" "chars[i] # Define separator here
}
printf "color joined: %s\n", joined
-2

Knowing that the opposite of split() is join(), a mere Google Search gives me this page, which seems to contain the solution : http://www.gnu.org/software/gawk/manual/html_node/Join-Function.html . It joins all the elements of an array together, and returns the corresponding string.

['f','o','o'] => "foo"

Have fun

  • 6
    The linked page refers to writing a function yourself. One of the answers that actually contains instructions in-line should be accepted (gnu.org is down at the time of writing). – Sam Brightman Aug 12 '16 at 08:40