小名开开

在春天的光影里喘息

前端炒面,后端烤串,

算法磨豆浆,中台煎饼灌。

商拓裹面粉,客服炸鸡块,

运维拉电线,硬件把煤担。

测试擦桌椅,UI洗碗筷。

总监跑堂勤,前台唱花旦。

产品经理沿街站,客官进来看。

文武十八艺,总有你一款。

日语输入法概述

日语常用的有罗马音输入法和假名输入法两种,前者类似于中文的拼音,后者则直接把按键映射为具体的假名。假名键位整体上输入速度会更快,多数情况可以一键一假名,还能减少 aiueo 五个键的磨损,但需要专门去记忆排布位置。罗马音键位则基本沿循了假名的音标注音,键位排布就是英语键盘也不需要重新学习。初步了解一下输入法软件的使用方法就可以上手打字了。

罗马音输入法的整体逻辑为:

  • 键入英文字符 -> 根据码表转假名
  • 根据假名选字 -> 进一步选择平假名、片假名,或展开列表择选汉字。
  • 回车或数字键确认选项 -> 上屏

而假名输入法相当于只是跳过了罗马音输入法的 西文字符->假名 这一步的转换,但后续的 决定平片假 -> 选字 -> 输出上屏 这几步一样。

所以对于初学者,使用系统自带的罗马音输入法就够了。

>
点击展开:罗马音键位、假名键位与 JIS 键盘收起

截图

罗马音键位 - 就是普通的英语键盘键位

截图

假名键位 - 非 JIS 键盘通常不会在键帽上印假名,需要心里默记

另外还有单独的 JIS 键盘布局和对应的键盘。以假名键位为基础,键盘上有单独的「半角/全角」、「片假/平假」、「变换/无变换」(用以选择输出汉字)等功能键。普通英语键盘则需要通过组合键实现这些功能。JIS 键盘在纯日语环境下会方便一些。

截图截图

JIS 键盘与键位表

扩展阅读 - 五花八门的中文输入法 [维基百科]

输入法的安装(Windows 和 MacOS,以及网页版)

手机端有另外的输入法和输入方式,另文再述。

Windows 和 MacOS 下都有系统自带的输入法。同时还有一些站点提供了在线方案,比如 Google Translate 的日语模块自带的输入法(需翻墙),不方便安装时可以考虑。

>
点击展开:安装过程详述收起

在 Windows 下需要在系统中先添加日语语言,再在语言下添加日语输入法。这里输入法的名字也叫「微软输入法」,和中文的同名,实际用的是罗马音输入方式,可以在输入法选项里进一步配置。

在 Windows 的系统设置中,先添加日语语言:

在日语语言选项中,添加日语输入法,顺便按需添加手写包和语音包,以防学习时遇到不会念的字导致无法输入:

在 MacOS 下,在设置内查找 键盘 -> 输入法,然后添加日文 - 罗马字输入法。MacOS 有几项设置比较重要,见文末补充

键盘 - 输入法

添加日文 - 罗马字输入法

如果两者都不想安装,也可以使用网页版的输入法,比如 Google Translate 的日语模块自带的输入法(需翻墙)。Google 翻译本身还能在学习过程中提供很多其它的帮助。

Google Translate

输入法的使用

输入法的使用包括:

  • 输入法的热键,输入状态的切换,以及平台间差异
  • 输入、选择模式与详细的罗马音码表
  • 一些特殊字符的输入方法

输入法热键(Windows)

对于日文输入法而言,存在三种状态分别为平假名、片假名、英文。在英文状态下相当于普通的英文输入法,输入英文字符直接上屏。热键也针对这三种情况有相应的配置。

输入法状态快捷键 功能
Win+Space
左 Alt+Shift
切换输入语言及该语言下的输入法。
Win+Space 会在屏幕上展示列表,而左 Alt+Shift 不会
Alt+`(数字 1 左边的键) 在假名和英文输入状态间切换,当从英文切回假名状态时,会恢复到上次切换为英文前的假名状态。平假名还是平假名,片假名还是片假名。
Ctrl+CapsLock 切换到平假名输入状态
Alt+CapsLock 切换到片假名输入状态
Shift+CapsLock 切换到全角英文输入状态。这状态下输入的英文字符都是全角的,同时仍然保留了择字功能,通过 Tab 而不是平常的 Space 可以选择列表项。
Win+. 打开 emoji 菜单
上屏菜单快捷键 功能
F6 当前输入内容转为平假名
F7 当前输入内容转为片假名
F8 当前输入内容转为半宽片假名
F9 当前输入内容转为全角英文
F10 当前输入内容转为半角英文
* F6 F7 F10 较为常用
Space(空格) 第一次拍击直接选择选字列表第一项,连续第二次拍击使光标进入选字列表,并逐个选择列表项
方向键 已经展开的选字列表里,定位选择列表项
Tab 如果没有拍空格而直接按 Tab,则光标进入选字列表,并逐个选择列表项。此时 Space 与 Tab 作用完全相同。
如果由 Space 启动的选字,则按 Tab 会使选字菜单横向展开成多列,方便使用方向键选字
Enter(回车) 确认当前光标位置的选字上屏
Ctrl-B 打开浏览器使用搜索引擎搜索当前输入内容(给浏览器引流)

输入法热键(MacOS)

MacOS 的热键与 Windows 有所不同,但基本功能相同。主要区别在于,在 Windows 下,输入法的状态切换是在输入法内部切换的,而在 MacOS 下,平假名 / 片假名直接作为两种输入法条目与 ABC(英文)并列,由系统输入法切换快捷键(通常是 Control+Space)统一切换。在输入法选项中可以设置只激活平假名输入,仍然可以通过 F7、择字等方式输入片假名和中文,不影响。

输入法状态快捷键 功能
Control-Shift-R 在当前光标处输入上一次确认的短句并重新择字
Control-3 直接在当前光标处打开颜文字选字列表
<以下快捷键需要先拖动光标使若干字处于文本选中状态>
Control-1 将选中文本转换为相关字符,通常就是选择假名使其在清浊音之转,也可以使漢字在不同书写形式之间转。例如,选择「汉」然后 Control-1 就会出菜单。类似的还有「假」与「仮」等
Control-2 根据选中文本搜索相似汉字,似乎是基于偏旁相似的,例如「假」与「葭暇瑕」等
Control-Shift-R 将选中文本先反转为读音,然后根据读音重新打开选字列表,用于同音不同字的勘误
上屏菜单快捷键 功能
Control-J / F6 当前输入内容转为平假名
Control-J / F7 当前输入内容转为片假名
Control-L / F9 当前输入内容转为全角英文
Control-; / F10 当前输入内容转为半角英文
Space(空格) MacOS 选字菜单是自动出现的,拍击使标进入选字列表,并逐个选择列表项。列表会自动展开
方向键 已经展开的选字列表里,定位选择列表项
Tab MacOS 选字菜单下方有分类列表,Tab 键切换
Enter(回车) 确认当前光标位置的选字上屏

输入法选字菜单

罗马字输入法的输入方式类似于拼音,键入英文字符,输入法弹出选词框,默认一般为平假名。用户用空格或数字键选择相同发音下的各种不同写法,择字确定后按回车上屏。初学者背完五十音图就不会有障碍。

示例:输入 shinjitsu 后按空格逐项选择想要的词组(含翻页),回车确定。也可用数字键直接择字。由于输入有明确意义,因此输入法第一建议是汉字的「真実」,第二选项才是平假名的「しんじつ」。 >

日语实际有的发音不止 50 音,以下是字符输入的全表。其中有部分音的输入码存在多种方式。输出结果是一样的,哪个音码习惯就用哪个。

清浊音表

あ゙ い゙ ゔ え゙ お゙
あア いイ うウ えエ おオ ゔヴ
a i/yi u e o vu
かカ きキ くク けケ こコ がガ ぎギ ぐグ げゲ ごゴ
ka ki ku/qu ke ko ga gi gu ge go
さサ しシ すス せセ そソ ざザ じジ ずズ ぜゼ ぞゾ
sa shi/si su se so za ji/zi zu ze zo
たタ ちチ つツ てテ とト だダ ぢヂ づヅ でデ どド
ta chi/ti tsu/tu te to da di du de do
なナ にニ ぬヌ ねネ のノ
na ni nu ne no
はハ ひヒ ふフ へヘ ほホ ばバ びビ ぶブ べベ ぼボ
ha hi fu/hu he ho ba bi bu be bo
ぱパ ぴピ ぷプ ぺペ ぽポ
pa pi pu pe po
まマ みミ むム めメ もモ
ma mi mu me mo
やヤ ゆユ よヨ
ya yu yo
らラ りリ るル れレ ろロ
ra ri ru re ro
わワ ゐヰ ゑヱ をヲ
wa wyi wye wo kyuukana kyuukana kyuukana kyuukana
んン
nn
  • じジ 与 ぢヂ、ずズ 与 づヅ 的读音是相同的,但在码表上则有区别,前者为 ji/zi zu 后者为 di du 以便于输入时区分。

  • ふフ 读作 fu,但输入法一般 fu 和 hu 都支持。

  • ヴ 是因外来语而补充的新假名,读作 vu,类似于英语里的 [v] 音。例如ヴァイオリン(Violin 小提琴)。在日常应用中,也可以以浊音 ブ 来标记。所以ブァイオリン也是对的。但发音上此处的 ブ 最好仍读作 [v]。

  • 由于 ヴ 本来就是新造词用于外来语表音,而日语中对音译词统一采用片假名表示,因此实际没有 ゔ 应用的场景。在微软输入法里无法通过 F6 或 Ctrl+CapsLock 切换到 ゔ,但可以通过空格下拉菜单实现。图例在 MacOS 下则直接展示 ゔ 并正常切换。

  • ゐヰ 和 ゑヱ 在现代日语中已经不再使用,只存在于古文和歌词中,例如《いるは歌》(伊吕波歌)。但在输入法上仍然保留,为避免与 いえ 重码,两者的音码调整为 wyi 和 wye。

  • 根据 维基百科,江户到明治期间,有过若干种 wu,即 わ行う()的独立假名写法出现在不同的文献中,但未有正式规范。字体文件和输入法也都不支持,既不能正常键入,也不能正常显示。や行い() 和 や行え()也有相同情况。

  • 用「kyuukana(旧仮名)」也可以输入旧时代的假名,比如「ゐ」、「ゑ」、「ゔ」等。这种输入方式属于以意定字,后面会有更多类似的例子。

  • 这三个音节的对应字符目前 在 Unicode 扩展词表中有定义,统归为「変体仮名」,使用定制的字体可以显示。本文采纳 Unicode 的写法,但使用 svg 图片代替显示。

  • 在实际的输入中,由于句子往往是片段或整句输入的,有些假名有两种输入方法(表中蓝字标部分),有些在输入时可以有一定程度的简略。类似于中文拼音里的容错、模糊音、联想功能。

  • 比如 ん,如果需要独立输入,需要按两次 n。但在实际整句输入中,会自动判断是否需要独立输入,经常只需要输入一次 n。比如「山田さんわ日本人です(山田先生是日本人)」这句,实际输入是:

    山田 さん 日本 です
    yamada san wa nihon jin desu

    这里さん(先生)的 ん 就只输入了一个 n,因为在日语中,ん 后面不会跟元音。因此在后续接 wa 时。输入法会自动把 n 转换成 ん。这里的 ん 确实可以输入 nn,但没必要。但若后续跟随的是元音时,为了区分就需要输入两次 n。比如 tanni(たんい,単位),若错输为 tani,就变成了たに(谷)。

常规拗音表

や゙ ゆ゙ よ゙
きゃ きゅ きょ ぎゃ ぎゅ ぎょ
kya kyu kyo gya gyu gyo
しゃ しゅ しょ じゃ じゅ じょ
sya/sha syu/shu syo/sho ja/jya ju/jyu jo/jyo
ちゃ ちゅ ちょ ぢゃ ぢゅ ぢょ
cha/cya/tya chu/cyu/tyu cho/cyo/tyo dya dyu dyo
にゃ にゅ にょ
nya nyu nyo
ひゃ ひゅ ひょ びゃ びゅ びょ
hya hyu hyo bya byu byo
ぴゃ ぴゅ ぴょ
pya pyu pyo
みゃ みゅ みょ
mya myu myo
りゃ りゅ りょ
rya ryu ryo
  • 常规拗音(通常直接称为拗音)只有 ゃゅょ 三列。它们和清浊表中 い 列的各个假名,组成一类转腔调的音。
  • 拗音当然也有片假名写法,表格空间有限,只写了平假名以作示意。
  • 虽然拗音表只有 36 个,但实际上输入法的码表中通常可以输出大量不在上表的可能的发音组合,用于表达各类外来语的发音,这些非常规的组合称为 合拗音
  • 其实,即使是在各种教材中作为标准音表存在的常规拗音,本身也是用于外来词音译发音的,只不过这个外来语是汉语。由于历史原因,常规拗音被视作日语本语言发音的一份,成为五十音图的增表了。

合拗音表

あ゙ い゙ ゔ え゙ お゙
うぁ うぃ うぇ うぉ いぇ
wha whi/wi whe who ye
きゃ きぃ きゅ きぇ きょ ぎゃ ぎぃ ぎゅ ぎぇ ぎょ
kya kyi kyu kye kyo gya gyi gyu gye gyo
くゃ · くぁ くぃ くゅ · くぅ くぇ くょ · くぉ ぐぁ ぐぃ ぐぅ ぐぇ ぐぉ
qya · kwa/qa/qwa qyi/qi/qwi qyu · qwu qye/qe/qwe qyo qo/qwo gwa gwi gwu gwe gwo
しゃ しぃ しゅ しぇ しょ じゃ じぃ じゅ じぇ じょ
sya/sha syi syu/shu sye/she syo/sho jya/zya/ja jyi/zyi jyu/zyu/ju jye/zye/je jyo/zyo/jo
すぁ すぃ すぅ すぇ すぉ
swa swi swu swe swo
ちゃ ちぃ ちゅ ちぇ ちょ ぢゃ ぢぃ ぢゅ ぢぇ ぢょ
cha/cya/tya cyi/tyi chu/cyu/tyu cye/che cho/cyo/tyo dya dyi dyu dye dyo
つぁ つぃ つぇ つぉ
tsa tsi tsu tse tso
てゃ てぃ てゅ てぇ てょ でゃ でぃ でゅ でぇ でょ
tha thi thu the tho dha dhi dhu dhe dho
とぁ とぃ とぅ とぇ とぉ どぁ どぃ どぅ どぇ どぉ
twa twi twu twe two dwa dwi dwu dwe dwo
にゃ にぃ にゅ にぇ にょ
nya nyi nyu nye nyo
ひゃ ひぃ ひゅ ひぇ ひょ びゃ びぃ びゅ びぇ びょ
hya hyi hyu hye hyo bya byi byu bye byo
ぴゃ ぴぃ ぴゅ ぴぇ ぴょ
pya pyi pyu pye pyo
ふゃ · ふぁ ふぃ ふゅ · ふぅ ふぇ ふょ · ふぉ
fya · fwa/fa fyi/fwi/fi fyu · fwu fye/fwe/fe fyo · fwo/fo
みゃ みぃ みゅ みぇ みょ
mya myi myu mye myo
りゃ りぃ りゅ りぇ りょ
rya ryi ryu rye ryo
りゃ りぃ りゅ りぇ りょ
rya ryi ryu rye ryo
ヴゃ · ヴぁ ヴぃ ヴゅ ヴぇ ヴょ · ヴぉ
vya · va vyi/vi vyu vye/ve vyo · vo
  • 合拗音表里标注蓝色的单元格写了两个拗音,因为码表里同时存在形如 くゃ 和 くぁ 两种拗音码,考虑到表格空间写在一起。两者是不同的码,不同的输出结果。
  • 同样,合拗音有片假名形式,表格写不下。或者说因为表外来语,合拗音主要是用片假名形式。
  • ヴ 行在 Windows 和 MacOS 下有不同表现。Windows 下默认输出形式为片假名 ヴ 搭配平假名拗尾,而 MacOS 下则直接输出片假名拗尾。另外 MacOS 下没有 vyi 和 vye 这两个码,只有 vi 和 ve。
  • 长拗音,例如「きょう(今日)」,是个发音的概念,但在输入法上正常写作 kyou,即常规拗音 きょ 接普通平假名 う 即可。这个词在罗马音注音上可能会写作 kyō,ō 即是拼音的第一声的符号。

特殊输入

日语里还有一些特殊的假名或符号,有些常用有些罕用,但整体都是被输入法支持的。这些特殊规则需要固定记忆:

小写假名及输入

输入小写假名需要使用 x 或 l 为前缀后正常输入音码,两个都可以,分别用左右手无名指击键,习惯哪个用哪个。小写假名大部分出现在拗音、外来语发音、特殊停顿等场景。

a i u e o
ぁァ ぃィ ぅゥ ぇェ ぉォ
la/xa li/xi lu/xu le/xe lo/xo
ゕヵ ゖヶ
lka/xka lke/xke
っッ
ltsu/ltu/xtsu/xtu
ゃャ ゅュ ょョ
lya/xya lyu/xyu lyo/xyo
ゎヮ
lwa/xwa
  • 可以看到,所有的拗音、合拗音中的第二个小写假名都可以简单地直接输入,所以拗音码表主要也是为了输入简化、更易配合发音习惯,并不需要特别记忆。
  • ゕゖ 与 ゔ 类似,可以通过空格下拉选项输入,但无法通过快捷键切换得到。这三者都是因为其片假名形式用于外来语,而额外添加的对应平假名。
  • ヵ一般只在量词中出现,「一ヵ月」。ヶ 也是,「三ヶ国」。这两个基本是同义的,源头其实就是中文的「箇(个)」。
  • ゎ 用于古拗音,比如 くゎんおん(观音)。按码表规律 くゎ 和 ぐゎ 两个拗音本应写作 kwa 和 gwa,但这两音码已经被 くぁ 和 ぐぁ 占了位置,所以只能输入 kuxwa。
  • っッ 在每个课程中都会讲到,表句中停顿,不详述。

特殊假名及输入

>>『 っッ 』
  • 表发音短促停顿的符号,除了 ltsu/ltu/xtsu/xtu 等以「小写つ」的形式输入外,还可以通过 复写下一个假名的首字母 的方式来输入。比如がっき(学期)→gakki,にっぽん(日本)→nippon。
  • 所以除了 nn 得ん以外,连写任意两个辅音字母都会出来「っ」,甚至「xxa」也能得到「っぁ」。这属于っ的单独输入逻辑。
>>『 ー 』
  • 在日语输入法中,直接按「-」键得到的就是「ー」。这个符号在日语中表示长音,主要用于片假名外来词,比如ケ一キ(蛋糕),偶尔也用在平假名中,比如おーいしい(美味しい)。
  • 相对的,若要输入英语半角减号「-」,需要按「-」然后空格下拉择字,或者快捷键切换到英文输入状态再按「-」。
>>『 ゠ 』
  • 「゠」名叫「二分二重双罫」,与等号相似但为独立字符。
  • 本意上表示外国人名、地区名转为假名时,两个单词间的隔断。比如ホー゠チ゠ミン(胡志明)。可以同时用于平片假名。
  • 这个符号实际上已经被抛弃,只在个别文章中还可以看见。现在一般用「・」来表示。大概是゠太容易和 =(等号)混淆了。
  • 输入法无法直接输入「゠」,甚至用 =(等号)空格择字都没有该字符。需要通过 Unicode 码表输入(&#x30A0;)。
  • 「゠」设计上还有一个「・」没有的作用,即对标英语的单词断行连接符「-」,用于外来词在行尾写不完转行时的标记。在英语中,当一个单词过长需要截断时,会在合适的音节处加「-」(减号)后回车换行,例如:
    Today is a big day, you got your first light-
    saber. Now you must go to Jedi Temple immedi-
    ately get your Jedi Knight certificate. May 
    the Force be with you.
    但在日文写作中「゠」的实际作用可有可无。和中文类似,日文换行也只需要直接另起即可,不需要专门标注单词连接。因而逐渐被彻底抛弃甚至不纳入输入法。
  • 考据来源:https://ja.wiktionary.org/wiki/%E3%82%A0

我觉得这就是黑船来航后全面西化时用力过猛的遗留。

>>『 ・ 』
  • 在日文输入法状态下直接按「/」(与问号同键)即可输入。
  • 和 ゠ 一样,表示外国人名、地区名转为片假名时,两个单词间的隔断。目前仍是常用符号。
>>『゛゜』以及>>『组合用゙゚』
  • 「゛」读作 dakuten(濁点),「゜」读作 handakuten(半濁点),分别表示清音、浊音假名的变化标记。输入也是这个拼写,在空格下拉列表中择字。
  • 这两个是独立的符号,不是附加在假名上的。正常输入浊音最好还是用浊音的音码。濁点主要用于特殊场合,比如本文说明部分,或者拼凑「い゛」之类时用到。
  • 因为是独立符号,所以在特殊场景下要考虑换行问题。比如「い゛」,如果在行尾,那么换行时濁点容易被带到下一行。
  • 「゙  ゚  」 是组合用浊点和半浊点符号。无法直接输入,只能通过复制粘贴或用 Unicode 码表输入「&#x3099;」和「&#x309A;」。相对的,普通「゛゜」的 Unicode 码则是「&#x309B;」和「&#x309C;」。两者码位不同,是不同的字符。
  • 「组合用」的意思是,利用了 Unicode 的偏移量特性,这两个符号会自动往左靠到前一个字符上。比如「い゙い゚」。
  • 组合用「゙  ゚   」输入麻烦,但其它好处较多。在很多操作中,い゙ 会完全地被当作一个字符,移动光标、选择复制或调整格式时都很方便。如果是「い゛」,在行尾换行时濁点容易被带到下一行。而 い゙ 则不会。
  • 在删除时,如果按 delete 删除光标右方的字,那么整个 い゙ 会被删除。如果按 BackSpace 删除光标左方的字,那么只会删除゙   ,い 不会被删除。
  • 在统计字数时,い゙ 会被当作两个字符。但在移动光标时会当作一个字符。在程序化编辑或 RPA 控制时需要单独处理。
  • Office 软件中插入符号功能可以比较方便地输入组合用 ゙ ゚   。
>>『 々 ゝゞヽヾ 〃 〱〲〳〴〵 』
  • 々表示连续两个相同汉字的第二个汉字的简写,比如「人々,ひとびと(人们)」,「先々月,せんせんげつ(上上月)」。
  • 在普通输入时,输入可以表示为两个相同汉字的音节时,输入法会将々自动作为候选词之一。
  • 当要单独输入时,输入 onaji(おなじ,同じ),意为「相同的」,然后在候选词中择字。思路类似于中文输入中的以词定字,或者说以意寻字。
  • 々 有一个 Windows 和 MacOS 都不支持,但 Google Translate 在线输入法支持的输入是「noma」下拉择字。思路是ノマ两字拼起来像是々。可谓以形寻字。
  • 基于「以意寻字」的逻辑,若输入 dou(どう,同)也可以择得这些字符,只是杂项会更多一些。Windows 还额外可以用 kurikaeshi(くりかえし,繰り返し)择得这些字符。
  • MacOS 可择字符比 Windows 少一些。
  • 当输入 おなじ 开始选词时,你会发现一连串的类似符号。
    • ゝゞ 分别表示清音、浊音平假名的重复,ヽヾ 表示清、浊片假名的重复
    • 〃 称为 ノノ字点(ののじてん) ,代表「与上方或前方对应位置的内容重复」。比如:
      站点 类型
      京东 购物网站
      淘宝
      拼多多
      4399 游戏网站
    • 〱〲 这两个就厉害了。它俩不是 くぐ,而是「竖排文本时表示前面两到四个假名的重复」,分别表示清音或浊音。并且在竖排文本书写印刷时,要占据两格长。
    • 〳〴〵这三个就更厉害了。因为上面两个符号要占据两格长,而通常来说哪怕是 Word 这种专业排版软件都很难让一个字符拉长占两个位置,所以发明了这三个字符,以便在竖写时可以拼成〱〲 。上半部分分清浊有两个,下半部分就只有一个。我试着在 Word 里拼了一下,在特定字体下的效果还不错。
  • 考据来源:https://en.wiktionary.org/wiki/%E3%80%B1

果然是黑船来航后用力过猛了。

>>『 ゟ 』
  • 读作 yori,输入也是 yori 后择字。用于在书面中表示书信的发件人,类似于中文里的「谨缄」「呈」,或路途的起点,类似于「始」「发」。这类字称为「合略仮名」(维基百科)
  • 日语中因为存在汉字训读,所以一个字符读两个音并不奇怪。这个字在明治以前经常使用,现在也还在看板招牌等处偶尔出现。
  • 中文曾有段时间也出现过合字的现象,最知名的是「瓩」,读作 Qīanwǎ,意思就是千瓦,电力功率单位,因为被收入字典而一度引发关注。多音节汉字大部分产生自外来语计量单位翻译,有兞兣兙兡兛兝嗧等若干字。
  • 但也有如「圕」这样,由文化名人自行创造的多音节汉字。「圕」最初被图书馆学家杜定友用于代替笔画繁多书写不便的繁体「圖書館」三字,一开始直接念作 túshūguǎn,即图书馆,后渐渐演化为 tuān,回归为单音节字。但在简化字方案中,「書」简化为「书」,「圕」则成为历史并未被简化字方案收录。理论上对应简化后的「」则作为一个扩展字符收入 Unicode - U+31578; 点位。
  • 合略假名页面中还列举了其它一些合略字,有不少暂时还没有被 Unicode 收录。
>>『 ヿ 』
  • koto。MacOS 自带日文输入法无此字,Windows 可以择得。
  • 字典的解释直接就是「事」の略体。ヿ 相关的短语包括ことにする、ことになっている等常用短语。但这个字本身很少用到,只有在书面语中才会出现。
  • 被定义为片假名,还有对应平假名形式的,但尚未在 Unicode 中收录,也无法输入。
>>『 〆 乄 』
  • shime。两者是同一个字,历史原因两者在字库中有独立的位置。MacOS 只能输入前者,而 Windows 两者都可以择得。Windows 下还可以用 shite 输入两个字符。
  • 主要用法是用密封的信封向对方寄送信件等时,以及强调信封已「封闭」牢固时。此外,它有时也有「收紧」、「扼杀」和「占领」的意思。
  • 组词包括「〆切(締切)」、「昆布〆(昆布締め)」、「尺〆(尺貫法の木材の体積の単位)」,「林方立木尺〆法(江户法律)」等。
>>『 〼 』
  • masu。各输入法都可以正常输入。
  • 这个字可厉害了,浪费了我一个小时。我一直以为它是某个字符不能正常显示时,替代出现的那种方框。但实际上它是一个独立的字符,并且还是个象形字。甚至在简体中文里我都从未见过如此象形的字。
  • 来,欣赏一下:枡
  • 释意一:是「枡」的替代字。用于表示「盛」、「量」、「桶」等容量单位,比如「一〼の酒」、「一〼の米」。「枡」就是上图这样的容器。
  • 释意二:ます 的简写,語尾「〜あり〼」,单纯用其发音。
  • 释意三:「益々(ますます)」的替代字,比如「〼〼のご発展を」。其实也是 ます 的替代简写。

符号与其输入方式

>>『 ← ↑ → ↓ 』
  • 用于表示方向,这个是符号,但和假名一样有专门的输入码。←(zh) ↑(zj) →(zk) ↓(zl)。
  • 熟悉 Vim 的知道这是 Vim 移动光标的键位。再往前考据则会涉及到 VI 的一段轶事
  • 一图胜千言:VimArrowKey
>>『 ○×△□ 』
  • 从这里开始就是符号了,输入法均使用以意定字的方式。列个列表方便看,表太长了放下面。
  • 除下表外,有个「kigou(記号)」可谓终极大法,可以选择输入法码表内的几乎所有符号。逐个翻阅吧。selection
  • 顔文字与絵文字是不同的,它俩的出现有先后,发展有联系。但单纯从字符角度来说,前者是用符号拼出来的,后者则是单独的字符。
  • 不同输入法支持的码、具体可选的符号数量有较大区别,下表在 MacOS 有很多不能输入。该表也不是全覆盖。
  • 有些码意义不大,比如「ando=&」不如 Shift+7 方便。但有些还是有用的,比如「kiroguramu=㎏」。要从符号堆里择出 ㎏ 很麻烦,直接输入哪怕多打几个字都可以。
  • 输入符号再按空格,也可以选择同类下形似的其它符号。比如输入「>」再按空格可以 择得「≫」。
  • 可以看到这些符号有些音类似于中文,有些音类似于西文。对照一下中文,像电力单位瓦、中文也是音译。但对于「公斤」,中文采用意译,而日文则直接音译。
意義 Romaji 記号例 意義 Romaji 記号例
矢印 yajirushi ⏩→▷⇨👉⇄ 数字 suuji 0️⃣1️⃣2️⃣3️⃣
ue ↑  ̄㊤ ↜↗↖⇑⇈↻↺☝ 上矢 ueya ↑↗⇡⇧⇑⇈➚
shita ↓_㊦ ↷↘⇂☟↧➷ 下矢 shitaya ↓↯↶⇩↡
hidari ㊧ ←↙↫⇠⇤↰⇦☚↩⇚⇇↸↜☜↚ 左矢 hidariya ←↢⇙⇦↖
migi ㊨ →⇒↛↱☞➳➔➴☛➢➠➪➫➤➥➲➺⇏➟➼ 右矢 migiya →⇒↗↝↛➭➬⇛➤➜➧
jou ge
ten ゜゛;:.,、´.・` ¨…‥∵・:;゙゚ ∴ 括弧 kakko 「」「」()【】“”
三角 sankaku ▾△▲▽▼∵∴◁ 四角 shikaku ■□◆◇▪▫▨▩❑❖▣◩
演算 keisan ≧÷±-× += ≠ < ≦ > 近似 kinji
恒等 goudou ≡≅≢ 不等号 futougou ≠≧⋝≳⋧≱≥≯≹
plus minus purasumainasu ±∓ root ru-to √∜∛
乘号 kakeru ×⋇⊠⊗ waru ÷⊘⋇∤
Percent pa-sento % Permillage pa-miru
何故ならば nazenaraba 故に yueni
斜線 shasen /\ 垂直 suichoku
kaku ∠⊥∟⊾∢∡ 直角 choltsukaku
Integral integuraru ∫∬∰∱∳∭⌠⌡ Phi fulai φΦ∮
無限大 mugendai 丸数字 marusuuji ①②③⑳❶❷❸
括号数字 kakkosuuji ⑴⑵⑶⒇ 罗马数字 ro-masuuji ⅠⅡⅢⅫ
図形 zukei ★○▼▽▲△■□◆◇◎●☆ 単位 tanni °′″℃ ¥$ € ¢£%Å ㍗‰㎜㍳℧℥℔ℓ㎯₪₦㏒
kome ヴィ bui
hoshi ☆✨💫🌟 星座 seiza ♈️♉️♊️♋️
天気 tenki 🌞🌤☁️☔️✨ kao 😃😂😇😍
osu mesu
音楽 ongaku 🎵🎼🎷🪕 音符 onpu ♪♬♫♩
Flat furatto AND ando ∩&∧⋀⋏
株式会社 kabushikikaisha ㈱㊑会社㍿ 有限会社 yuugengaisha (有)㈲㊒
代表 daihyou (代)㈹ 土/度 do ℃°℉ ㊏㈯
maru ●○◎◉⚫︎⚪️⭕️💮 バツ batsu ×❌❎✖️
二重丸 nijuumaru hishi ◆◇❖
黒星 kuroboshi 黒丸 kuromaru
白星 shiroboshi 白丸 shiromaru
te 👉✊🙏👌 郵便 yuubin 〒 📮🏧📦
チェス chesu ♟️ トランプ toranpu ♤♡♧♢🃏
電話 denwa ℡✆☏☎ Number nanba- №#
en cent sento ㌣¢ ¢
Pond pondo £ Dollar doru $$
摂氏 seltsushi JIS jisu
centi senchi ㎝ ㌢ 千米 kirome-toru
平米 heibei 立方 Meter rippoumi-teru
千克 kiro/kiroguramu Litre rittoru l lℓ
milli miri ㎜ ㍉ milligram miriguramu
昭和 shouwa 平成 heisei
大正 taishou 明治 meiji
Section sekushon § chuu ㊥㊟
左上 hidariue ┏┌╒╓┎╭╔┍ 左下 hidarishita ┗└╘╙┖╰╚┕
右上 migiue ┐┓╕╖┒╮╗┑ 右下 migishita ┘┛╛╜┚╯╝┙
tate │┃ |¦ ∥╵║¦❚┆❙ yoko ━─┈╌┄┉╍═
太枠 futowaku ┗┻━┛┏┳━┓ 細枠 hosowaku └┴─┘┌┬─┐
满中 mannnaka ┼╂╋┿╃╁╳╬╪╫ 罫線 keisen <上全部及更多>
ase (・・;)(^_^;) itai (>_<)
居眠 inemuri (-_-)zzz 御茶 ocha ( ^^) *U~~ ( ^^) *旦~~
Wink ulinku (^_-)-☆ 嗯—— u-n (゜-゜) (゜.゜) (゜レ゜)
奥特曼 urutoraman (o|o) えっへん ehhen <(`^´)>
跪拜/抱歉 ojigi/gomen _(._.)_ <(_ _)> 徹夜 tetsuya (=_=)
闪亮 kirakira ☆ ミ ☆ 彡 ごぼごぼ gobogobo .。o○ ○o。.
じと jito (-.-) (--) (ーー)!! じろ jiro ( 一一) (;一_一)
一服/烟 ippuku/tabako (-。-)y-゜゜゜
(^。^)y-.。o○
あわ awa .。o○   ○o。.
動物 doubutsu (=^・^=) <*))>=< C:。ミ neko (=^・^=) =^_^=
哈依 ha-i (^O^)/ 何故/謎 naze/nazo (?_?) (・・?
吃驚 bikkuri ( ゚ Д ゚) 无语 muka (-"-)(ーー゛)(-_-メ)
顔文字 kaomoji <以上全部及更多> 絵文字 emoji 😱😓
>>『 ā ī ū ē ō 』
  • 这是用于在罗马音注音中表示长音的符号。比如「おかあさん okāsan 妈妈」,「おにいさん onīsan 哥哥」,「じゅうにがつ jyūniketsu 十二月」,「おねえさん onēsan 姐姐」,「おとうさん otōsan 爸爸」。
  • 尽管如此,日文输入法却无法输入这五个字符,没有对应的码表,也没有以意寻字的方法。在きごう下择字也同样找不到这几个。
  • 对于中文用户,输入这几个字符最方便的办法是直接切换到中文输入法,然后调出软键盘等符号功能,然后在拼音符号中择字输入。
  • 其次的方法是在 Word 等软件中,使用插入符号功能,找到对应字符输入。或在相关功能的网页上复制粘贴。
  • 如果要经常使用,可以在输入法的用户自定义词典里添加,并分配对应的输入码。
  • 一般不需要担心输入问题,通常会使用 ā=aa ī=ii ū=uu ē=ee ō=ou 代替。随着发音变迁,ē 有时也会写作 ei。[参考]

默认情况下,vmware 虚拟机的硬盘空间可以在 vmware 的虚拟机设置里调整大小,但只能『扩展』,却无法缩小。

截图
当输入较小数字时,按钮变灰,无法点击。

问题:为什么要缩小虚拟机硬盘

一,vmware 的虚拟硬盘文件 *.vmdk 默认是动态分配空间的,没有数据的虚拟 “硬盘空间” 并不占用真实主机的实际硬盘空间。当虚拟机内需要储存更多数据时,对应的 vmdk 文件会相应增大,以便容纳新增的数据。但当虚拟机内的数据被清理时,已经增大的 vmdk 文件却不会自动缩小。随着虚拟机的不断使用,『只增大不缩小』的情况会逐渐严重,直到 vmdk 体积达到预设的虚拟机硬盘完整容量为止。
临时文件、虚拟机快照、积累性的文件复制与删除操作等各种情况都会增大 vmdk 体积。vmware 针对这种情况提供了 shrink disk(压缩硬盘)功能,也就是在虚拟机数据已经被清除后,整体扫描一遍 vmdk 文件,清理无效数据,缩小真实体积。但这也有两个麻烦:

  1. 因为膨胀永远存在,所以压缩也要经常进行,难免感觉在做无用功。
  2. Linux 下 shrink 功能有 bug,需要配合 dd 命令先以 0 数据充,相当于先撑大再缩小,耗时数倍。参考:第四条豆知识

二,很多情况下,我们安装虚拟机的用途都比较单一,虚拟机的实际硬盘占用也往往小于 vmware 的推荐值。这是实际需求方面及可操作方面。

三,强迫症 / 好奇 / 无理由。

于是,根据实际使用情况,适当降低虚拟机的硬盘容量,将『使用膨胀』的上限卡住,释放真实硬盘空间并避免经常的压缩操作,对时间和金钱都有好处。尤其是现在 SSD 逐步标配的阶段,虚拟机硬盘容量设置不当造成的浪费是很可观的。

问题:如何操作

我以一个当初决策不当分配了 40GB 硬盘空间的虚拟机 Windows XP 为例,重新调整的目标为 10GB。一般来说,全新安装的 Windows XP 大约占 4-5GB 空间,则我们还有约 5GB 空间可用来安装测试软件等,足够了。如果不够就自行酌情决定调整目标。

一、清理删除当前虚拟机下的所有快照,如果这些快照很重要不能删,那接下来的操作对你就没意义了。

二、确认虚拟机硬盘是拆分成多个文件的动态分配硬盘。本例子中,该虚拟机的所有文件放在 D:\Program files\Windows XP.vmwarevm 目录下。用 VSCode 打开虚拟机目录下和虚拟机同名的 *.vmdk 文件,如 『Windows XP.vmdk』。找到 # Extent description 部分,检查描述部分,一看就懂了。如图:

打开 vmdk 时几种可能的情况:

  • 如果有多行描述,并且每行写了 SPARSE ,这就是我们需要的类型,拆分+动态分配磁盘。直接跳过后续转格式步骤,进入修改分区步骤即可。
  • 如果有多行描述,但每行写的是 FLAT ,则为拆分的预分配磁盘,需要转格式。
  • 只有一行描述,写的是 FLAT ,则是单一文件预分配磁盘,也需要转格式。
  • 如果乱码或者提示打不开,则是单一文件动态分配磁盘,还是需要转格式。

VMWare 在新建虚拟机时会默认选择第一种类型,但玩家当初可能出于性能等考虑,选择了其它类型的虚拟硬盘。那么就需要使用 vmware 自带的一个命令行工具

1
vmware-vdiskmanager.exe

转换成第一种类型。该工具在 vmware 安装目录下,默认为 “C:\Program Files (x86)\VMware\VMware Workstation\vmware-vdiskmanager.exe”。

转换方法:

该工具的命令行写法为:

工具名 参数 1 源文件 参数 2 参数 3 目标名称
vmware-vdiskmanager -r(转格式) Windows XP.vmdk(例) -t(目的) 1(目的磁盘类型,1 为拆分+动态分配) newdisk.vmdk

该命令中, -r-t 1 两部分不需要变化,目标名称 随意,之后会改名覆盖源文件。源文件名 根据实际情况变化,而 工具名 通常要带上路径。

所以完整的命令大约是如下样子:

1
"c:\Program Files (x86)\VMware\VMware Workstation\vmware-vdiskmanager.exe" -r "d:\Program Files\Windows XP.vmwarevm\Windows XP.vmdk" -t 1 "d:\Program Files\Windows XP.vmwarevm\newdisk.vmdk"

回车以后开始执行转换:

转换完成以后,删除旧的 “windows XP.vmdk” 和多个关联文件 “windows XP-s0xx.vmdk”,然后把新的 newdisk.vmdk 重命名成 “windows XP.vmdk” 以替换。其它 newdisk-s00x.vmdk 不用变。

三,打开虚拟机,进入系统。

  • 在虚机机内,使用分区管理软件将硬盘分区缩小,并将空闲保留在右端,分区块保持在左端。我们的整体目标是从 40GB 缩到 10GB,则现在要多缩一点给后续操作留出余量。如图,暂时缩到 9GB。
  • Windows 7 以上系统,自带的磁盘管理就有『压缩卷』功能可以调整分区大小,WinXP 用的是 DiskGenius 免费版本。Win98 则需要寻找更古老的相应软件。
  • 中途可能需要重启虚拟机,无妨,调整完关闭虚拟机即可。

四,加减乘除:

再次打开 Windows XP.vmdk 文件,定位到 # Extent description 部分。这次重点放在第二部分数字内容上,经计算,该数字为每个分块文件对应虚拟硬盘的簇数量,每簇 512 Byte,2 簇 = 1KB。我们的目标容量为 10GB,也就是:

  • 10(GB)*1024(MB/GB)*1024(KB/MB)= 10485760 KB = 20971520 簇。

检查 # Extent description,前两个文件每个 8323072,则把第三行的数字改为

  • 20971520 – 8323072*2 = 4325376


并删掉后续各行及对应文件,我们就在 vmware 部分完成了虚拟机硬盘大小调整。

五,补足余量:

重开虚拟机。前次调整分区时,预留了 1GB 左右的余量。再次打开分区工具,把剩余未使用空间重新分配给各分区。

因为对计算机分区而言,由于存在分区表、启动扇区等原因,物理上的 10GB 硬盘空间在系统内表现是略小于 10GB 的,『内』『外』之间有差额,这对于虚拟机也一样成立。如果一开始就分区 10GB 而外部调整也等 10GB 的话,再次启动虚拟机就会报分区表错误,界时修改起来反而麻烦。现在这样按先预留余量,而后补足分区操作就没问题了。

六,清理死数据:

由于直接修改了描述文件,改小了簇数量,-s003.vmdk 里原本存于 4325376 之后的数据变成了永久的『死数据』。关闭虚拟机后,需要使用 vmware-vdistmanager -r -t 1 再作一次转换。虽说是转换,但目的却是清理死数据。清理完以后直接单独替换新旧 -s003.vmdk 即可。(想想为什么?)

————————————————-

相关细节:

  • 虚拟机为 Linux 系统时原理一样。利用 GParted 等分区工具,首先缩小使用分区,并调整未分区块到尾端。关机编辑 vmdk 描述,开虚拟机调整补分区足余量,再用 vmware 提供的工具清理死数据即可。
  • 预分配类型的虚拟硬盘必须先 vdiskmanager 转类型,不能直接操作。追求性能的话在编辑完再转回去。不过追求性能的话应该上 SSD,一力降十会。
  • 编辑 .vmx 和 .vmdk 文件不要用 windows 自带的记事本。
  • 虚拟机备份直接复制整个目录即可。
  • 扩容不需要按本文操作,使用 vmware 自带功能即可。

脚本文件里的 Hybrid Script(混合式脚本)

上文曾介绍了混合式脚本的原理和示例,这里补充一个实际适用的场景。

问题描述:

在 Windows 下,即使正确关联了 .ps1 的打开方式,Powershell 也无法正常运行脚本,只有一闪而过的报错信息。

正确设置了 PowerShell 的关联

使用录屏软件捕获到这一闪而过的错误信息

而首先打开 PowerShell 终端,并在终端里指定执行脚本,则可以正确执行:

脚本本身没有问题

错误原因:

这个错误原因其实挺显然的——在 Windows 下双击执行,等同于运行 PowerShell.exe,并向其传入了脚本文件的完整地址作为参数。但 Windows Explorer 在传递 %1 时没有加引号,PowerShell.exe 也没有对此做检查。结果就是,只要脚本所在的目录含有空格,PowerShell.exe 就会把空格前半段视为文件地址,而把空格后半段视为另一个运行参数。

而通过先启动终端再指定脚本运行正常,就是因为没有传参这个过程,Powershell 自行请求了脚本文件,就能正常执行。

解决办法

解决办法却不容易。修改双击打开时的参数设置为其加上引号,这个太困难了。修改 PowerShell 程序本身,为其添加参数检查更是不可能,只能坐等微软更新。

剩下的只有两种办法,一是永远把 .ps1 脚本放在没有空格的目录里。不但本目录不能有空格,上级目录一直到盘符所在的根目录都不能有空格。这其实也挺麻烦的。

另一种办法就是用混合式脚本:

  • 代码示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<# : test.ps1.bat
@ECHO OFF
powershell -noprofile "iex (${%~f0} | out-string)"
goto :EOF
:: 以上是 bat 代码,用以正确向 PowerShell 传递带空格路径 / 以下是 PowerShell 代码,示例用的 echo #>

echo ""
echo ================================
echo "You can run PS1 correctly here."
echo "But can't run it by double click."
echo ================================
echo ""

cmd /c pause | out-null

虽然我们要写的是 PowerShell 脚本,但为了让脚本能支持在含空格的路径下双击执行,我们不得不首先以批处理文件的形式调用 CMD,然后让 CMD 向 PowerShell 正确地传递带上引号的完整路径。这样,PowerShell 就能正确识别脚本文件的位置,执行混合脚本里的 PowerShell 代码段,完成最初预期的功能。

  1. 双击运行效果:
    混合脚本显示的是 CMD 的黑窗口

因为混合脚本首先运行的是 CMD,所以窗口变成了黑色。但 PowerShell 的脚本确实正确执行了。

题外话:

  1. 通常这种混合脚本我都会按语言命名为 ***.ps1.bat 以区别普通的 .bat,并提醒用户(也就是我自己)这需要 Windows 安装了 Powershell 才能正确执行。PowerShell 可以从 Windows 的系统组件里添加,Win10 则已经自带了。
  2. 为了截图方便,上文的示例代码最后一行其实又用到了 CMD 代码的 pause,所以这个示例代码严格来说是 CMD → Powershell → CMD 的三阶混合脚本。

因为日常需要,经常写一些脚本命令,比如 Windows CMD / PowerShell / bash 之类的。最近学习了一种新的脚本类型:Hybrid script,即混合式脚本,是在一个脚本文件内,同时使用多个语言的语法和对应功能。比如以下这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<# : hybrid.bat
@ECHO OFF
if "%~1" == "" goto SELECT
bin\youtube-dl -a "%~1"
goto :EOF

:SELECT
setlocal
for /f "delims=" %%I in ('powershell -noprofile "iex (${%~f0} | out-string)"') do (
bin\youtube-dl -a "%%~I"
)
goto :EOF
:: end Batch portion / begin PowerShell hybrid chimera #>

Add-Type -AssemblyName System.Windows.Forms
$f = new-object Windows.Forms.OpenFileDialog
$f.InitialDirectory = pwd
$f.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
$f.ShowHelp = $true
$f.Multiselect = $true
[void]$f.ShowDialog()
if ($f.Multiselect) { $f.FileNames } else { $f.FileName }

这段代码的功能是调用 youtube-dl.exe,按预先准备的待下载视频列表指示,下载所有视频。有趣的是,如果你通过拖拽的方式,把列表放到脚本文件图标上,则脚本直接开始按列表下载。

如果没有拖拽,而是双击打开脚本文件,则会跳出一个选择文件的 Windows 对话框,让用户选择一个或者多个列表,然后再开始下载。

这是一个用户体验相对比较好的方法。虽然这脚本只是自用,但我自己也是比较烦命令行的。至于任务是下载视频,或者处理音频,亦或删除目录什么的,只是中段执行不同,和本文主旨无关。

这脚本的核心难点,便是『如果没有拖拽列表文件,则打开窗口让用户选』这个需求点。CMD 是没有 Windows 图形界面下的对话框功能的,但 PowerShell 有。因此便有了这个 Hybrid Script 脚本。

脚本前半段是 Batch 代码,输入下载列表文件路径,执行下载。这个『下载列表文件路径』,或者是用户拖拽获得,或者是用户在选择窗口中操作获得。后半段则是 .ps1 代码,用来绘制选择窗口并把列表路径返回 CMD。

但问题在于,两种代码并不兼容。CMD 并不能识别 PowerShell 代码,而 PS 也无法识别 Batch 代码。如果普通的执行对方的代码,一定会报错的。

于是我们看到,上面这段代码里似乎有几行奇怪的代码:

1
2
3
4
5
<# : hybrid.bat
......
goto :EOF
......
:: end Batch portion / begin PowerShell hybrid chimera #>

没错,就是这几行特殊代码,以及另一个非常重要的变量 %~f0,决定了 Hybrid Script 的可行性。

事实上,<# ... #> 是 PowerShell 的注释代码,PS1 执行器遇到它时,会直接忽略两者中间的所有内容,执行后面的代码。而 <# :hybrid.bat 对 CMD 而言是个没有指定目标的左向重定向命令。因此 CMD 确实执行了第一行,但没有任何效果。

对于 PS 的结束注释符号 #>,在 CMD 看来确实有意义。但我们提前用 goto :EOF 直接跳到脚本最末(End-Of-File)的办法,把这一行以及后面的所有代码都跳过了。于是这些代码在 CMD 下的对错就无关紧要了。

也就是说,在 CMD 眼睛里,这段代码其实是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
<# : hybrid.bat
@ECHO OFF
if "%~1" == "" goto SELECT
bin\youtube-dl -a "%~1"
goto :EOF

:SELECT
setlocal
for /f "delims=" %%I in ('powershell -noprofile "iex (${%~f0} | out-string)"') do (
bin\youtube-dl -a "%%~I"
)
goto :EOF

而在 PowerShell 眼里,这段代码是这样的:

1
2
3
4
5
6
7
8
Add-Type -AssemblyName System.Windows.Forms
$f = new-object Windows.Forms.OpenFileDialog
$f.InitialDirectory = pwd
$f.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
$f.ShowHelp = $true
$f.Multiselect = $true
[void]$f.ShowDialog()
if ($f.Multiselect) { $f.FileNames } else { $f.FileName }

以上都明确以后,中间那句

1
powershell -noprofile "iex (${%~f0} | out-string)"

的作用也就容易理解了:Batch 脚本调用了 PowerShell 的执行器,并把这个 hybrid.bat 自己(在 Batch 代码中,%~f0 这个变量就是指脚本文件自己)传递给了 PowerShell。

PowerShell 接到消息以后,又执行了一遍这个 Hybrid.bat。这次是 PS 视角,因此上来就忽略了前面整大段的“注释”,直接从 Add-Type -AssemblyName System.Windows.Forms 这段开始,绘制窗口,等待用户选择,获得列表文件路径,然后再返回给 CMD。CMD 最后再执行 for /f "delims=" %%I in ( ...... ) do ( ...... ) 的部分,并根据 goto :EOF 的指示,跳过剩余代码,避免了在 CMD 环境下的报错。

因此,为了正确执行功能,Hybrid Script 的核心思想是:

1. 利用两种语言的注释符号的不同,隐藏非执行环境下的代码。
2. 灵活应用两种语言的特性,确保任一语言下的注释符号本身,对于另一种语言没有负面效果。
3. 首先执行的语言 A,需要把脚本文件自身的路径,传递给另一种语言 B 的执行器。
4. B 语言的执行器,忽略掉被 B 语言注释符号包裹起来的 A 语言代码,执行 B 的代码,如果需要的话,把执行结果返回给 A。
5. A 继续执行剩下的部分,忽略掉被 A 语言的注释符号包裹起来的 B 语言代码。
6. Hybrid Script 至少会执行两遍,可能更多。

———————————————

充分理解 Hybrid Script 思想以后,我们就知道这并不仅仅限于 Batch 和 PowerShell 脚本的混合了。常用的几种脚本语言都可以实现混合代码。实践中:

1. Windows Batch & Windows PowerShell
2. Windows Batch & Linux Bash
3. Windows Batch & Python
4. Windows Batch & Javascript
5. Linux Bash & Python
6. Linux Bash & Javascript
7. NodeJS & Python
8. …

等等组合都可以写出相应的混合代码脚本。

Hybrid Script 能同时利用两种甚至多种语言的方便特性。并且对于各语言组合,相互注释的『套路』是固定的,几部分代码实际功能如何变化并不影响套路。但其实整体来说适用性不广,一来机器上需要同时有两种语言的运行环境,二来 Python JS C# 等几种主流语言都有完备的功能集和函数库,不需要跨语言写作。三来,即使真的需要两种语言,大部分情况下也可以写成两个脚本互相调 用执行。

只有很少的几种情况下需要考虑 Hybrid Script,包括:

1. 因为传播渠道问题,不适合拆分成多个脚本的。比如互联网上常见的『复制粘贴代码到记事本改后缀为 .bat 然后双击运行』。
2. 代码票友,对 A 语言和 B 语言都不甚精通,或者从 A 转 B 的学习过程中,B 还不甚了解,需要用 A 语言的代码补足。
3. A 语言确实功能有限,但胜在编码方便历史普及率高。而产品虽需要却也只需要 B 的极小功能。比如本文示例。
4. 写着玩。


5. 解决 PowerShell 无法正确处理文件路径带空格的 BUG,参见:

Hybrid Script 附一则:解决 PowerShell 无法双击打开路径含空格文件的 Bug

今天遇到一个奇怪的情况,在使用形如:

=Match(A2,A:A,0)

的 Excel 公式查找时,居然返回了 #N/A 的结果。逻辑上来说,在自己所在的数组里查找自己,不应该得到错误结果,事实上这个公式的值只可能是 1 或者 2 才对。

经过检查,发现问题出在字符 ~ (波浪号)上,即键盘上 ESC 键的下方,数字 1 的左边那个键的 Shift 上档符号。

Excel 官方帮助文档 中,找到了相关的解释。

如果 match_type 为 0 且 lookup_value 为文本字符串,您可在 lookup_value 参数中使用通配符 – 问号 (?) 和星号 (*) 。问号匹配任意单个字符;星号匹配任意一串字符。如果要查找实际的问号或星号,请在字符前键入波形符 (~)。

这里提到了,当使用 Match() 函数进行精确的文本查找时可以使用通配符 ? 和 *,当用户确实需要查找问号/星号时,则可以用 ~? 和 ~* 来表示。这里没有提到的是,如果用户需要查找 ~,其实也需要通过两个波浪号 ~~ 来表示。转义符自身也需要转义表达,也算是一般规则了。

所以,如果一个单元格中包含了波浪号 ~,则当这个单元格作为被查找的数据的一部分时,是正常的。但当它同时作为 lookup_value 时,则会在转义后变得无实际意义。于是导致了 Match() 函数查找自身所在数组时产生的错误结果。

遇到这个问题时,我正在处理由家用下载机长年积累下的大量动画片资源。用 Bash 获得所有的动画目录名、文件名,并试图尽量删减一些重复资源。文件名系统中并不存在『 ? * : < > | / \ ” 』等符号,但偏偏允许波浪号 ~ 的存在。又因为在 Excel 的默认字体中,波浪号并不显示为扭曲的波浪形状,而是略长的横线,如图,于如是尴尬便发生了。

解决办法:

给 lookup_value 添加一个 SUBSTITUTE() 函数进行修正,即:

1
=Match(Substitute(A2,"~","~~"),A:A,0)

即可得到期望结果。

一句话总结:

match_type 为 0 且 lookup_value 为文本字符串时,使用 =Match() 函数时需要注意 lookup_value 是否包含 ~ 、?、* 并根据需要预先做处理。

Ikaruga「斑鸠」 on Steam

来,跟我念:

黑机吃黑弹躲白弹打白鸡留黑鸡给白队友遇白光切白机。
白机吃白弹躲黑弹打黑鸡留白鸡给黑队友遇黑光切黑机。

黑白黑白黑白黑黑白白黑黑黑黑白黑白黑白黑白黑白黑黑黑白黑,
变变变变变变变定变定变定定定变变变变变变变变变变定定变变。

黑白黑黑白白白黑白白黑白黑白白黑黑白黑白黑黑黑白白黑黑黑黑黑白白白黑黑黑白黑黑白白黑黑白黑白黑黑黑黑白白白白白白,
变躲吸吸变吸吸躲吸吸躲吸变躲躲吸吸躲吸躲吸吸吸放大招吸吸吸吸变吸吸变吸吸变躲躲吸吸变吸躲吸躲吸吸吸躲变吸吸放大招。

……差不多这个感觉。

Ikaruga 斑鸠

如果说彩京、虫姬、东方是用层层叠叠的华丽弹幕压迫你的灵魂让你手脚冰凉让你奋起反抗让你一世积累尽殁此役,那么斑鸠则是用至简与朴素唤醒你心底的温暖,唤起你对理想与光明世界的向往。

这个世界没有遮天蔽日的弹幕,每一个子弹都可以直接吸收无需躲避,
这个世界没有血条畸长的敌人,即使是关底 Boss 也挡不住几轮蓄能爆发,
这个世界的敌人甚至还会在死去时抛出剩余的能量帮你充能,
这个世界不断地告诉你什么叫理想、试练、信念、现实与轮回。
这个世界总是将光明放在你的眼前,触手可及。

一个完美的世界。

这个世界里里唯一不完美的是你。是屏幕前双手颤抖面目狰狞的你,是竭力紧抓手柄胡乱变色仓皇逃窜的你。但这个世界依然爱着你,从内到外都爱着你。

没有 给你任何 随机出现的敌人,只有约定之时,只有约定之地。
她给了你远超需要的强大技能,蓄能爆发,让你在瞬间打倒最强大的敌人。
她给了你 异色双倍伤害,给了你 三同色击破链式加分,给了你破敌 残弹 额外蓄能。
她还给了你 竖屏模式,将显示器旋为竖置,世界便扩大八分。
她甚至给了你 单手柄双机模式,让最孤独的你也能与自己一起游戏。
她唯独只是 没有 给你 网络联机 模式,她是完美的,她不需要的,便是不需要的。

你只需要做好一件事,在该变白时变白,该变黑时变黑,你就能回应她的爱,双双走向高潮。

你怎么就做不到呢。

甚至最后的最后,她为了如此不成器的你,把 无限命模式 也给了你。

完美的她,深深地爱着毫不完美的你,爱着什么都做不到的你,爱着靠无限命死乞白赖撒泼打混的你,爱到了最后。

这份爱,只需 36 人民币,打折 18。

参考老文章: Overwatch Toolchain 解包方式考察\,OW 音频小站一直以来使用原始文件 hash 的办法,便每次更新以后,都能区分旧数据和新增数据,使得每次更新的条目数量都在合理范围。但从版本 1.14 开始,暴雪更新了内部数据格式,这个是由蓝帖明确提到的,目的是减少之后的每次客户端更新时的下载。

但这对本小站来说不亚于一次冲击。这意味着,直到 1.13 版为止的条目,和从 1.17 版开始的所有条目,无法从数据角度建立『新』与『旧』的联系。

也就是说,明明从用户角度来说是同一句台词,音频波形也一致,但由于 OW 内部格式的变化,导致 hash 计算的结果变化,使得从数据角度来说,它们变成了两个不同的条目。

比如: 【D.Va】D.Va 一分,坏蛋零分。(1.17 版本) 的 hash 计算结果是 5908654fbc3965232689836abb249c57,而
【D.Va】D.Va 一分,坏蛋零分。(1.16 或更早版本) 的 hash 计算结果是 1d99c1739f5b0844f57f3a1a5fbb4580

我做了很多尝试,试图恢复一些信息,把这些本质相同的音频重新联系起来,有些成功了,有些失败了。最后我把匹配成功部分更新到原有条目上,匹配失败的部分按『新增音频』对待,添加到数据库里。

  1. 尝试使用音频分析软件批量比较,如果成功,理论上这是最好的办法。
    • 这是本质的解决办法,如果两个音频文件的波形完全一致,则两个音频当然是一样的。
    • 尝试了 Audacity 和 Similarity,前者缺乏批量功能,后者无法对这种只有一两秒的音频进行比较,均告失败。
  2. 尝试使用新版本拆解工具拆解旧客户端,失败,但得到了启发。
  3. 因为拆解所用的 Toolchain 工具链(简称 TC)本身有自己的文件名系统,而我亦保留了过去所有版本的原始拆解数据,理论上能通过新旧版本文件的相同路径名等信息恢复联系。
  4. 测试以上两条 D.VA 音频的 TC 路径分别为:
    • 旧(1.13):cn\heroes\D.Va\Sound Dump Full\_Base\000300000057\000000020231.wem
    • 新(1.18):cn\HeroVoice\D.Va\00000000059F.078\000000020231.wem
  5. 测试成功。
  6. 进入实操,发现由于旧版本拆解工具的不完全,数据存在错误,依然有许多坑要填:
    • 一,多个不同的 TC 文件名对应同一个 hash,即多个 1.18 新文件条目对应同一个 1.13 旧条目 hash,错误在旧版拆解工具自带的文件名系统有 bug。
      • 解决办法是视为多个条目,并将旧条目的听写内容更新到各个新条目上。
      • 对于网站用户来说,同一个关键词可能会搜索出几条内容,但其中应该至少有一条是对得上的
    • 二,同一个 TC 文件名对应多个一个 hash,即同一个 1.18 新文件条目对应多条旧的 1.13 旧条目,显然错误还是旧版折解工具的不完善
      • 解决办法只能是人工筛选按多条里面正确的那条。
      • 大约一共有 1200 条这种类型的错误,一条一条听完。网站用户肯定会得到正确的结果,因为这部分我都筛完了。

这次更新正常应当在 1.14 新版数据格式更新,1.17 新版拆解软件开发成熟以后更新,但这数据处理是真 TM 麻烦啊,烦死了。

Grep 字典式匹配输出

1
grep -f source.txt dictionary.txt > output.txt

SED 若干则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 匹配成功输出
sed -n '/匹配成功/p' file.txt >output.txt

# 多个脚本并行执行
sh script01.sh & sh script02.sh & sh script03.sh

# 一般的正则替换
sed -i -e 's/^[0-9a-f]\{2\}/target\//g' a.txt

# 文件名无空格的列表输出
for file in $(find lib -name '*.txt'); do
echo "$file" >>liblist.txt
done

# 文件名有空格的列表输出
find lib -type f -name '*.txt' -print0 |
while IFS= read -r -d '' file; do
echo -e \"$file\" >>liblist.txt
done

# 计算文件 hash 值,用 cut 切掉输出时自带的文件名
hash=$(md5sum "$file"|cut -c1-32)

CMD 快速删除文件

1
2
3
4
5
6
7
:: 极快速删除所有文件
del /f/s/q *.*

:: 快速删除目录与子目录与文件
rmdir /s/q dir

:: 后者包含前者,但前者速度比后者快

Excel:从右往左查找某个字符。

1
=FIND("|",SUBSTITUTE(A2,"/","|",LEN(A2)-LEN(SUBSTITUTE(A2,"/",""))))

原理,使用 Substitute() 将所查找的字符替换为空,则长度差代表该字符出现的次数。将该次数作为 substitute 函数的第四参数,用一个特殊字符再度进行 Substitute() 替换,然后 Find() 该特殊字符。注意替换用的特殊字符(这里是"|",即Shift+\)不能在A2中出现,否则必须换一个。

目前适用于 ngacn 论坛帖子,效果图如下:

启动脚本后,会依次询问你 nga 的帖子 id,总页码数量和帖子名称。脚本会自动检查是否之前已经抓取过该帖子并在上次抓取的最后一页开始继续往下抓取。

每个帖子的抓取结果会放在独立的目录,并以”帖子 id”-“自定义名称”的形式储存

注意事项:

  1. 脚本会优先检查是否有 $tid-xxx 形式的目录,只要 $tid 一致,脚本就认为本次会在旧的内容基础上往后抓取截图,xxx 的名称可以是任意的,不检查。假如已经存在一个 『12345-上山打老虎』 的目录,而你第二次输入的是 『12345-钻石王老五』,则实际更新的依然是『12345-上山打老虎』 目录。
  2. 目录名称中间的减号必须保留,否则脚本会忽略已存在的目录,按新目录工作执行。目录内的 1.update.sh 文件也必须保留。
  3. 我的运行环境是 Win10 64 位 1703 版本,不保证在其它机器上能正常运行。在 Win10 下脚本文件可以直接双击打开,在 Win7 下可能需要右键点击并选择用 Git Bash 打开。
  4. 需要预先安装该脚本所需要的环境才能正常运行,包括 node、bash 等。

安装与准备工作:

  1. 下载并安装 Node for win 使 Windows 获得本截图脚本所需的 node 语言支持: 下载网址: https://nodejs.org/en/download/ ,选择下载 LTS 版本下对应的 32 位 或 64 位 Windows Installer。安装一路 next 就行。
  2. 下载并安装 Git for win 使 Windows 也能使用 Bash 脚本。下载网址:https://git-for-windows.github.io/ ,也是一路 next 默认安装就行。
  3. 从开始菜单找到 Git Bash,,点击运行,在黑色窗口内依次输入以下内容:
1
2
3
npm config set registry https://registry.npm.taobao.org
npm i -g npm@latest
npm i -g pageres-cli

效果:

  1. 新建一个目录,起个名,比如叫『nga 截图收藏夹』之类的。
  2. 在目录下新建一个文本文件,复制粘贴以下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/bin/bash

#User input

tid=""
totalpage=""
title=""
while [[ ! $tid =~ ^[0-9]+$ ]]; do
echo -e "输入 NGA 帖子 id:"
read -r tid
done
while [[ ! $totalpage =~ ^[0-9]+$ ]]; do
echo -e "指定该帖子的总页数:"
read -r totalpage
done
echo -e "起个标题备注(可以自定义):"
read -r title

#Check if $tid follder is exist

for _dir in "${tid}-"*; do
[ -d "${_dir}" ] && targetdir="${_dir}" && break
done
if [ -z "$targetdir" ]; then
echo "建立一个新目录"
foldername=$tid"-"$title
mkdir "$foldername"
cd "$foldername"
touch 1.update.sh
echo -e "#!/bin/bash" >>1.update.sh
echo -e "startpage=\"1\"" >>1.update.sh
echo -e "totalpage=\""$totalpage"\"" >>1.update.sh
echo -e "tid=\""$tid"\"" >>1.update.sh
echo -e "rm \"page\"\$startpage\".png\"" >>1.update.sh
echo -e "for i in \`seq \$startpage \$totalpage\`" >>1.update.sh
echo -e "do" >>1.update.sh
echo -e " page=\"http://bbs.ngacn.cc/read.php?tid=\"\$tid\"\&page=\"\$i" >>1.update.sh
echo -e " fn=\"page\"\$i" >>1.update.sh
echo -e " echo \$page" >>1.update.sh
echo -e " pageres \$page --filename=\$fn" >>1.update.sh
echo -e "done" >>1.update.sh
echo -e "sed s/^startpage=\\\".*\\\"\$/startpage=\\\"\$totalpage\\\"/g 1.update.sh >u.tmp" >>1.update.sh
echo -e "mv -f u.tmp 1.update.sh" >>1.update.sh
else
foldername=$targetdir
echo "发现旧的工作目录,在此目录上更新:"
echo $foldername
cd "$foldername"
sed s/^totalpage=\".*\"$/totalpage=\"$totalpage\"/g 1.update.sh >u.tmp
mv -f u.tmp 1.update.sh
fi

sh ./1.update.sh

echo "Work Done"

随便起个名,并把后缀名改为 .sh。如何修改后缀名请自行百度。

使用:

  1. 双击,依次输入帖子 id,最后一页页码和标题就可以用了。

尾注:

  1. 如果你懂得简单的编程,可以尝试阅读脚本,并自行修改以抓取其它网站的贴子。这个脚本的原理就是利用 nga 帖子很有规律的地址,通过指定帖子 tid、页码 pageid 拼接出需要抓取的指定页面网址,然后反复调用 pageres 去抓取。实际进行抓取的是一个叫 pageres 的 npm 小程序。
  2. 如果你懂得简单的 JS,你可以自行指定 pageres 的抓取参数,甚至包括登录的 cookie 等,以实现『个性化抓取』。
  3. 如果你会完整的 node 开发,希望这个脚本也能为你提供一些参考。
0%