3

I have string like this:

Grades ABCDEF-123456

I want to split this string to two sections like this

Grades ABCDEF
Grades 123456

How can I do that in bash?

0

4 Answers 4

6
echo Grades "ABCDE-12345" | sed 's/-/ /g' | awk '{ print $1" "$2"\n"$1" "$3'}
Grades ABCDE
Grades 12345

or per @steeldriver

awk -F'[ -]' '{print $1, $2; print $1, $3}'
1
  • 3
    There's really no need for sed here - just set the FS to include - i.e. awk -F'[ -]' '{print $1, $2; print $1, $3}' Commented Oct 8, 2018 at 18:09
3

You can do this entirely in your shell, too:

text="Grades ABCDEF-123456"

Split off the leading text. You could capture it if required, but here we'll just discard it:

grades="${text#* }"

Now we could extract the two parts as variables but for now we'll just print them:

echo "Grades ${grades%-*}"
echo "Grades ${grades#*-}"

You can also crash these together into a single output statement, but I don't think it's as readable (even if printf is safer than echo for certain classes of text):

printf "Grades %s\nGrades %s\n" "${grades%-*}" "${grades#*-}"
3

You can do it by replacing the dash with a newline followed by the first field:

perl -alpe 's/-/\n$F[0] /' 
0

Using Raku (formerly known as Perl_6)

~$ raku -ne 'my @a = .split("-", 2); put "@a.[0]\n", @a.[0].words[0], " @a.[1]";'   file
Grades ABCDEF
Grades 123456

#OR:

~$ raku -ne '.split("-", 2) andthen put "$_.[0]\n", $_.[0].words[0], " $_.[1]";'   file
Grades ABCDEF
Grades 123456

Raku is a programming language in the Perl-family. There are fewer command-line flags in Raku as compared to Perl. Above, the Raku one-liner is called with -ne non-autoprinting linewise flags.

First Answer: The linewise input is .split on - hyphen into 2 pieces, and assigned to @a array. Note that .split is short for $_.split meaning to call the routine on the $_ topic variable, in this case the line text. Once in the @a array, all we have to do is massage the data into the proper output format. Raku's words routine breaks text at whitespace. So the final put call can be understood as follows:

  1. "@a.[0]\n" print the first element of @a followed by newline,
  2. @a.[0].words[0] print the first word of the first element on the next line,
  3. " @a.[1]" on the same (second) line, print space then the second element of @a.

Second Answer: If you're comfortable using $_ topic variables, you can forgo the array assignment and get the same output. Note in the second answer above that the $_ is optional and the code can be further shortened: all you need is the leading . dot for Raku to understand that you want the routine/index called on the $_ topic variable.

Finally, adding a key "prefix" to various text snippets is a common task. If you're comfortable with key/value pairs and can accept the default sorting, the code below might be conceptually simpler (returns \t-separated columns):

~$ raku -ne 'my %hash = .words[0] => .words[1].split("-", 2);  \
             for %hash.sort {.antipairs.put for .invert };'   file
Grades  ABCDEF
Grades  123456

https://docs.raku.org/routine/split
https://docs.raku.org/routine/invert
https://raku.org

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.