UNIX/Linux shell 脚本:从文本中删除变体形式的表情符号
UNIX/Linux shell script: Removing variant form emoji from a text
假设您正在使用 Linux/UNIX shell,其默认字符集是 UTF-8:
$ echo $LANG
en_US.UTF-8
您有一个文本文件 emoji.txt,它以 UTF-8 编码:
$ file -i ./emoji.txt
./emoji.txt: text/plain; charset=utf-8
此文本文件包含一些表情符号和一个变体形式的转义序列:
$ cat ./emoji.txt
Standard ☁
Variant form ☁️
$ uni2ascii -a B -q ./emoji.txt
Standard \x2601
Variant form \x2601\xFE0F
您想删除两个表情符号,包括那个变体字符 (\xFE0F),因此输出应该是
Standard
Variant form
你会怎么做?
更新。这个问题不是关于如何删除每一行中的最后一个词。想象一下 emoji2.txt 包含一个带有许多表情符号字符的大文本;其中一些后面是变体形式序列。
将Unicode文本文件转换为ASCII并去掉那些由ASCII字符表示的Unicode字符,并再次将其转换为UTF-8:
$ uni2ascii -q ./emoji.txt | sed "s/ 0x2601\(0xFE0F\)\?//g" | ascii2uni -q
Standard
Variant form
$
使用 GNU sed
和 bash
:
sed -E s/$'\u2601\uFE0F?'//g emoji.txt
让 awk
打印除最后一个字段之外的所有字段:
$ awk '/^Standard/ || /^Variant form/ { $(NF)="" }1' emoji.txt
Standard
Variant form
注意:此特定解决方案将在输出行的末尾保留字段分隔符(空白);如果你想去除尾随空白,你可以通过管道传输到 sed
、tr
等...或者让 awk
循环遍历字段 1 到 (NF-1) 并通过 printf
您可以使用 awk
,像这样:
$ cat emo.ascii
Standard \x2601
Variant form \x2601\xFE0F
$ ascii2uni -a B emo.ascii
Standard ☁
Variant form ☁️
3 tokens converted # note: this is stderr
$ ascii2uni -a B emo.ascii | awk -F' ' '{NF--}1' | cat -A
3 tokens converted # note: this is stderr
Standard$
Variant form$
NF--
将减少 awk 中的字段数,从而有效地删除最后一个字段。 1
计算结果为真,这使得 awk 打印修改后的行。
(这里使用cat -A
只是为了表示没有留下任何不可见的字符)
使用nkf
命令。 nkf -s
尝试将字符编码转换为不支持表情符号的 Shift-jis。因此,表情符号和转义序列将消失。最后,使用 nkf -w
.
将输入恢复为 UTF-8
$ cat emoji.txt | nkf -s | nkf -w
Standard
Variant form
$ cat emoji.txt | nkf -s | nkf -w | od -tx1c
0000000 53 74 61 6e 64 61 72 64 20 0a 56 61 72 69 61 6e
S t a n d a r d \n V a r i a n
0000020 74 20 66 6f 72 6d 20 0a
t f o r m \n
0000030
我认为 ruby
可能有效。因为 \p{Emoji}
匹配表情符号。但它仍然是转义序列..
$ ruby -nle 'puts $_.gsub!(/\p{Emoji}/,"")' emoji.txt
Standard
Variant form ️
$ ruby -nle 'puts $_.gsub!(/\p{Emoji}/,"")' emoji.txt | od -tx1c
0000000 53 74 61 6e 64 61 72 64 20 0a 56 61 72 69 61 6e
S t a n d a r d \n V a r i a n
0000020 74 20 66 6f 72 6d 20 ef b8 8f 0a
t f o r m 217 \n
0000033
假设您正在使用 Linux/UNIX shell,其默认字符集是 UTF-8:
$ echo $LANG
en_US.UTF-8
您有一个文本文件 emoji.txt,它以 UTF-8 编码:
$ file -i ./emoji.txt
./emoji.txt: text/plain; charset=utf-8
此文本文件包含一些表情符号和一个变体形式的转义序列:
$ cat ./emoji.txt
Standard ☁
Variant form ☁️
$ uni2ascii -a B -q ./emoji.txt
Standard \x2601
Variant form \x2601\xFE0F
您想删除两个表情符号,包括那个变体字符 (\xFE0F),因此输出应该是
Standard
Variant form
你会怎么做?
更新。这个问题不是关于如何删除每一行中的最后一个词。想象一下 emoji2.txt 包含一个带有许多表情符号字符的大文本;其中一些后面是变体形式序列。
将Unicode文本文件转换为ASCII并去掉那些由ASCII字符表示的Unicode字符,并再次将其转换为UTF-8:
$ uni2ascii -q ./emoji.txt | sed "s/ 0x2601\(0xFE0F\)\?//g" | ascii2uni -q
Standard
Variant form
$
使用 GNU sed
和 bash
:
sed -E s/$'\u2601\uFE0F?'//g emoji.txt
让 awk
打印除最后一个字段之外的所有字段:
$ awk '/^Standard/ || /^Variant form/ { $(NF)="" }1' emoji.txt
Standard
Variant form
注意:此特定解决方案将在输出行的末尾保留字段分隔符(空白);如果你想去除尾随空白,你可以通过管道传输到 sed
、tr
等...或者让 awk
循环遍历字段 1 到 (NF-1) 并通过 printf
您可以使用 awk
,像这样:
$ cat emo.ascii
Standard \x2601
Variant form \x2601\xFE0F
$ ascii2uni -a B emo.ascii
Standard ☁
Variant form ☁️
3 tokens converted # note: this is stderr
$ ascii2uni -a B emo.ascii | awk -F' ' '{NF--}1' | cat -A
3 tokens converted # note: this is stderr
Standard$
Variant form$
NF--
将减少 awk 中的字段数,从而有效地删除最后一个字段。 1
计算结果为真,这使得 awk 打印修改后的行。
(这里使用cat -A
只是为了表示没有留下任何不可见的字符)
使用nkf
命令。 nkf -s
尝试将字符编码转换为不支持表情符号的 Shift-jis。因此,表情符号和转义序列将消失。最后,使用 nkf -w
.
$ cat emoji.txt | nkf -s | nkf -w
Standard
Variant form
$ cat emoji.txt | nkf -s | nkf -w | od -tx1c
0000000 53 74 61 6e 64 61 72 64 20 0a 56 61 72 69 61 6e
S t a n d a r d \n V a r i a n
0000020 74 20 66 6f 72 6d 20 0a
t f o r m \n
0000030
我认为 ruby
可能有效。因为 \p{Emoji}
匹配表情符号。但它仍然是转义序列..
$ ruby -nle 'puts $_.gsub!(/\p{Emoji}/,"")' emoji.txt
Standard
Variant form ️
$ ruby -nle 'puts $_.gsub!(/\p{Emoji}/,"")' emoji.txt | od -tx1c
0000000 53 74 61 6e 64 61 72 64 20 0a 56 61 72 69 61 6e
S t a n d a r d \n V a r i a n
0000020 74 20 66 6f 72 6d 20 ef b8 8f 0a
t f o r m 217 \n
0000033