5

I have a file in the format of:

 ⌚..⌛    watch..hourglass
 ⌨️       keyboard
 ⏏️       eject button

Where some lines contain two entries. I want to break lines with 2 entries into 2 lines like so:

 ⌚       watch
 ⌛       hourglass
 ⌨️       keyboard
 ⏏️       eject button

Is there a fast way to do this?


My script:

#!/usr/bin/env bash

wget -O output.txt http://www.unicode.org/Public/emoji/6.0/emoji-data.txt

sed -i '/^#/ d' output.txt                        # Remove comments                                                                                                          
sed -i 's/.*(//' output.txt                       # Remove columns not needed                                                                                               
sed -i 's|[(),]||g' output.txt                    # Remove brackets around emoji                                                                                         
sed -i 's/\(.*[^ ]\)[ ]*\(.*\)/\2 \1/' output.txt # Move first column to last                                                                         
sed -i '/^$/d' output.txt                         # Remove blank lines

Tried @RomanPerekhrest's answer on the following (answer has been updated):

 ↔️..↙️    left-right arrow..down-left arrow
 ↩️..↪️    right arrow curving left..left arrow curving right
 ⌚..⌛    watch..hourglass done
 ⌨️       keyboard

and it works on watch/hourglass but not the ones above(?)

1
  • Seriously, when you need to do complex logic you'd be better off writing a Perl/Python script and call that script. After all, you're already calling an external program (sed). You don't even have to make the Python/Perl script a separate file; just embed the script in the bash script.
    – pepoluan
    Apr 7, 2022 at 7:29

3 Answers 3

4

UPDATE

Fixed an issue with some emoji being followed by the variation-selector-16, resulting in a bad formatting.

See @jimmij's answer, for an even more optimized sed script !

sed

 sed '/.\.\./ s/\(.\)\.\.\(\S*\)\s*\(.*\)\.\./\1\t\3\n \2\t/'
4

Another sed version, based on zeppelin answer, but simpler and aligned - taking care that unicode are not always single-characters. Tested with gnu sed.

sed 's/\.\.\([^ ]*\) *\(.*\)\.\./\t\2\n \1\t/'

Output:

 ↔️      left-right arrow
 ↙️      down-left arrow
 ↩️      right arrow curving left
 ↪️      left arrow curving right
 ⌚      watch
 ⌛      hourglass done
 ⌨️       keyboard
5
  • sed does match unicode characters correctly indeed (taking that you have a Unicode locale set), but some of the emoji are followed by variation-selector-16, which is a non-spacing mark (but not a part of the preceding character). I've updated my answer to take it into account, after looking at yours :) Thx !
    – zeppelin
    Aug 21, 2017 at 17:15
  • @zeppelin I didn't know about these "selectors", thanks. So technically speaking there are two unicode characters: original and the following selector, is that correct? If so, can original exist without selector block?
    – jimmij
    Aug 21, 2017 at 17:43
  • Yep, original character can exist w/o a variation selector. It is more like a display hint, see unicode.org/faq/vs.html for a more in-depth explanation of their role.
    – zeppelin
    Aug 21, 2017 at 18:32
  • \t\2\n \1\t - Whitespace is not needed here. It do extra indent.
    – MiniMax
    Aug 21, 2017 at 20:03
  • 1
    @MiniMax Yes it does, as a whitespace at the beginning of the line is present in the OP question.
    – jimmij
    Aug 21, 2017 at 20:26
3

awk solution:

awk -F'[[:space:]][[:space:]]+' '$1~/\S\.\.\S/ && $2~/\S\.\.\S/{ 
         split($1,a,/\.\./); split($2,b,/\.\./); 
         printf("%s\t%s\n%s\t%s\n",a[1],b[1],a[2],b[2]); next 
     }1' file
  • -F'[[:space:]][[:space:]]+' - field separator

  • $1~/\S\.\.\S/ && $2~/\S\.\.\S/ - if 2 fields contain .. as subitem separator

The output:

↔️  left-right arrow
↙️  down-left arrow
↩️  right arrow curving left
↪️  left arrow curving right
⌚   watch
⌛   hourglass done
⌨️       keyboard
2
  • Sorry to slightly change my question but I'm trying to figure out why your code matches for the watch hourglass case but none of the other similar cases in my data file. Aug 21, 2017 at 15:46
  • @PhilipKirkbride, don't worry, see my update Aug 21, 2017 at 15:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .