在 git 1.7 版本之前,你是没法只 checkout 版本库中的一个子文件夹出来的,现在已经可以实现了,主要通过新引进的 sparsecheck 这个功能做到的。Git 的这个功能其实还是会把远端服务器上的版本库上的内容都先同步到本地,然后只解压缩显示你想要的子文件夹出来。

在新库下同步

  1. 创建和初始化一个新版本库
    mkdir <repo> && cd <repo>
    git init
    git remote add –f <name> <url>
  2. 开启 sparse-checkout 功能
    git config core.sparsecheckout true
  3. 将要同步到本地的子文件夹名配置到 .git/info/sparse-chekcout 文件中
    echo some/dir/ >> .git/info/sparse-checkout
    echo another/sub/tree >> .git/info/sparse-checkout
  4. checkout
    git pull <remote> <branch>

在已有版本库下同步

如果你已经有一个版本库,那么前两步操作同上,第三步使用 read-tree 命令

  1. 开启 sparse-checkout 功能
    git config core.sparsecheckout true
  2. 将要同步到本地的子文件夹名配置到 .git/info/sparse-chekcout 文件中
    echo some/dir/ >> .git/info/sparse-checkout
    echo another/sub/tree >> .git/info/sparse-checkout
  3. 更新当前库
    git read-tree -mu HEAD

更换子文件夹到本地

如果想要更换同步到本地的子文件夹,只需要修改 sparse-check 文件并且如上重新执行 read-tree 命令。


本文主要参考这篇文章

本文主要内容来自这本仅 23 页的小手册《A Beginners Guide To App Analytics》。

随着移动设备的大量增加,移动端流量比重的稳步增长,对 APP 应用的分析日趋重要。

一、改变思考方式

首先要改变以网站为中心的思考方式,现在是在分析移动端的 APP 应用,两者有几个很不同点。

焦点在用户访问会话(user sessions)上,而不是访问页面数(pageviews)!

在一个时间段内,人们花在 APP 上的时间可能比在网站上的时间更短,但是却会更专注。使用 APP 和使用网站的转换流程可能大体相似,但是在数据分析上却极不相同。对 APP 的分析焦点在用户访问会话(user sessions)上,而不是访问页面数(pageviews)!

在 APP 上对访问会话有更准确、更详尽的追踪,每次会话都是一个相对紧凑和完整的单元。在网页上的浏览行为会因为浏览器 cookie 环境的变化而对用户追踪不准确,也会因为浏览器多标签的功能而无法准确地记录用户访问路径,对每次访问的时间也没法准确记录,因为用户可能保持页面打开的同时转到外网页面浏览,或者用户访问站仅是为了找回一些信息,而不会有潜在的转化行为。而在移动端情况则很不一样,可以通过移动设备或者社交认证确认用户身份,每次用户访问会话结束的标记是用户关闭了该 APP 应用或者跳转到其他地方超过了 15 秒,用户在 APP 上的访问行为都能被准确地记录下来。

二、仅有下载是不够的

大概有 22% 的下载量带来的使用不超过一次,所有仅有下载量是远远不足的。好的应用研究者需要深入评估留存情况,用户使用习惯和转化效果。

三、为你的目标给出正确的分析

衡量用户的参与度(engagement)有一系列的指标可用,但是你能从中得到什么取决于你的整体品牌目标是什么。对于一个 APP 来说,开发者、市场营销人员、销售人员甚至商业主管可能都有自己各自不尽相同的目标,所以先绕着为什么要启动 APP 要弄清几个问题:

step_why_launch_app

各种 APP 可能大不一样,所以先针对你的商业目标制定合适的指标是首要的事。带着问题开始分析能给你一个快速的可行性强的起点。

四、8 个关键的度量指标

心里已经有了一些分析目标但是还不知道从哪里开始?下面列有 8 个通用的度量指标,可以作为一个很好的分析起点。

1. 用户(User)

辨识你的用户是首要的关键一步。它不仅能让你对你的用户有更深的了解,熟悉他们的使用习惯,还能推进一些更深入的项目,如用户细分(segmenting audiences),跟踪用户的特殊行为,发起一些成功的 APP 营销活动。当你知道了用户基数和当前活跃用户数,你也就得到了一个基准线以分析下次增加用户数的活动。同样的,你也能更了解用户的有价值行为,包括用户的购买行为和广告点击行为。

2. 会话时长(Session Length)

会话时长是指从用户打开 APP 到关闭或者跳转到其他地方超过 15 秒这段时间的时长,它表示用户每次使用 APP 花了多少时间。

跟踪用户的会话时长对释放用户的交易潜力很关键。假设一个电子商务的应用,结算过程需要花多少时间呢?如果平均的会话时长是 5 分钟而你的结算过程需要花费 6 分钟,那么你要么想办法鼓励用户停留更长的时间,要么简化结算流程。

3. 会话间隔(Session Interval)

这里会话间隔指的是用户首次与二次访问之间的时间间隔,表明用户使用 APP 的频率。这个指标标志着下载和运行 APP 后体现出来的直接价值。当你知道了每个用户群体的会话间隔时间,就可以提供更好的用户体验以促进用户使用。

比如,你注意到平板用户的会话间隔时间比手机用户更长,那么你可能需要改进平板上 APP 的屏幕流或者设计以缩短平板用户的会话间隔时间。这也表明你应该加一些有关系的市场推广活动,如应用内推送或者消息推送。

4. 使用 APP 的时长(Time in APP)

使用 APP 的时长是指在一段时间内用户在 APP 的停留时间,比如用户 X 在过去的 24 小时内花在我们应用上 3 个小时。这是另一个度量你的应用多经常被使用,也代表了你的应用对用户的价值。

如果有一部分用户经常长时间的使用你的应用,你需要深入了解“为什么”?他们的屏幕流是否相识,是否购买更多,还是在做研究?用这样的信息可以推出更个性化的宣传口号。

5. 应用获取(Acquisition)

应用获取量代表从某个渠道下载并安装应用的量,比如通过自然搜索,口口相传,付费活动或者其他应用的外链。当你想发起付费活动来推广 APP 时,应用获取这个指标就显得很重要。这方面可以体现你花了多少钱来获得这些用户,下载量以及用户打开应用后的使用情况。

进行付费推广活动的分析最终要落到 ROI (Return on Investment),而不是仅仅看下载量。你需要对照着自然获得的用户来分析比较推广获得用户的长期价值,切分用户做 A/B 测试,或者通过不同的消息通知来促进转化。

6. 屏幕流(Screen Flow)

屏幕流能跟踪屏幕的退出情况,屏之间的跳转,每屏的访问次数,可视化用户在应用内的访问路径。通过屏幕流,你可以分析一些特定屏,看看用户在这个页面上做了什么以及后续去了哪些页面。通过访问路径的分析,可以发现问题页面,发现转化瓶颈页面以及退出页。

7. 留存率(Retention)

留存率是度量有多少比例的用户在他们首次使用 APP 后还会返回。按照设备类型、用户群体、市场活动或者用户的购买频率等维度来分别跟踪留存率可以帮助分析市场活动和个性化营销的效果以及改进 APP。

当应用更新后,分析留存率能让你知道哪些在起作用,哪些没有,你需要确定新版本发布后留存率是否有发生变化。建立长期的留存率监控能促进主要用户的转化和购买,因为培养 APP 的高频使用用户是进行用户生命周期价值管理和促进收益的关键。

8. 生命周期价值(Lifetime Value)

生命周期价值是衡量收益的主要指标,表示该 APP 的金融价值和每个用户在其生命周期中的价值。它也能分割到平均每月的价值,捕获到随时间变化的客户价值,或者用忠诚度和传播度来描述。比如,对一个新的 APP 来说,它的价值能被文章的阅读数和分享数来衡量。LTV 也能通过每个用户的收益来衡量,和购买略微不同却直接相关。

对于不同的用户群体,LTV 的增长会随着时间而表现出差异,或许是因为下载渠道或者是回复率不同的群体,这些也是给你信号,可以持续投入去获取这样的用户,从而转化出利润。它也能表明移动端和非移动端的价值,哪部分群体更愿意花钱,更忠诚,更愿意作为企业的布道者。

五、APP 分析的 4 个最佳实践

任何分析都要结合实际的业务,上面所提到的 8 个指标只是分析的起点。

1. 标记事件

一个事件就是用户在 APP 内的一个行为,是达到我们目的的可定义的每一步,比如文章被阅读是一个事件,转发到社交网络也是一个事件。事件可以伴随着自己的属性,方便更细致地描述每一步,比如事件“文章被分享”是一个事件,他的属性有平台和文章 ID。

标记一个事件意味着这个事件总是被记录着。比如你有一个电商的 APP,那么关于最重要的“支付流程”漏斗转化的每一个事件都应该被记录下来,这包括用户浏览商品,加入购物车,开始结算流程并完成每一步,到最终的确认页面并完成购买。

其他的事件可以包括广告被点击,文章被阅读,邀请好友,参与玩游戏,视频被点播。

2. 细分客户

如果你的用户行为都一样,那么做分析和改进你的 APP 真是一件简单的事情。但事实是用户行为差别很大。一个细分是根据用户是否有触发某个或某些事件来定义的,比如购物车放弃。

3. 选择客户维度

客户维度能很好地对客户进行细分。最基本的比如可以查看不同的设备和模式上的应用内行为。一些好的用户维度有用户的注册状态,订阅类型,性别等。一般而言,用户维度是被视为半持久的用户属性,并且不会经常变更。

4. 定义漏斗转化

APP 的转化漏斗和网页端定义一样,它是你希望你的用户在 APP 内转化的流程。

本文主要是总结下 sed 的一些常规用法,主要参考酷壳的这篇文章“sed简明教程”,还有 sed 的官方手册。sed 是 stream editor 的缩写,也即是流编辑器,将输入流按照命令做相应的编辑变换的工作。本文主要是作为学习 sed 的一个总结,帮助记忆,挂一漏万是难免的了。

sed命令的格式一般如下:

sed [命令参数]  [脚本]  [输入流(如文件名)]

如下,就是将文件 my.txt 中的第1到3行所有 my 替换为 your,第3行到文件尾的 This 替换为 That,并最后将替换后结果写回文件 my.txt 中。

$ sed -i '1,3s/my/your/g; 3,$s/This/That/g' my.txt

命令参数

几个常用的选项有:

-i 直接编辑原文件
-n 安静模式,不输出

脚本部分

脚本部分用单引号或双引号包围,内部可以分为多个命令,用分号隔开,如下:

命令块1;命令块2;...;命令块n

其中每个命令块的格式如下:

[匹配范围][!][sed命令 [命令参数]]

匹配范围

可以指定单行或者指定一个范围,可以直接写行号,如指定第1行 "1",或者从第3行到文件尾 "3,$";还可以通过形式 "/pattern/" 来指定找到该模式的行,如 "/dog/,/cat/" 代表从含有单词 dog 的行开始,到其后第一个含有单词 cat 的行结束,如果没有找到含有 dog 的行则后面的命令不被执行,如果有开始但是没有找到含有 cat 的行则命令会从开始行执行到文件尾。匹配范围还可以指定相对行数,如 "/dog/,+3" 表示的范围是第一个含有 dog 的行及其后3行。

如果匹配范围省略则命令对输入流的所有行都执行。

sed 命令

在 sed 命令前加上感叹号代表在指定的匹配范围内不执行该命令,其他行则执行。

a 命令,即在找到的行后 append 后面的内容,如下就是将第2到第5行每行后都加入一行“---***---”

$ sed "2,5a ---***---" my.txt
This is my cat
my cat's name is betty
---***---
This is my dog
---***---
my dog's name is frank
---***---
This is my fish
---***---
my fish's name is george
This is my goat
my goat's name is adam

i 命令,与 a 命令类似即在找到的行前 insert 进后面的内容。
c 命令,即将找到的行替换为后面的内容,如下,就将第2到第5行替换为“---***---”

$ sed "2,5c ---***---" my.txt
This is my cat
---***---
my fish's name is george
This is my goat
my goat's name is adam

d 命令,即将找到的行 delete。
p 命令,即将找到的行 print 出来。
N 命令,把下一行的内容纳入缓冲区做匹配。
s 命令,这个应该是最重要也是最常用的命令,substitute 替换,一般的使用格式如下:

s/pattern-source/pattern-destination/pattern-flag

其主要就是将匹配到的 pattern-source 的内容替换为 pattern-destination 的内容,如果熟悉 vim 的就会发现此处和 vim 中的s替换是一致的,也使用正则表达式匹配,也一样可以使用圆括号匹配。pattern-flag 可以使用 "/g" 代表所有能匹配上的都进行替换 globally,如果不加此则每行只替换第一个匹配上的模式,还可以使用 "/I" 代表匹配不区分大小写 Ignore Case。下面是关于 s 命令的一些例子。

$ cat my.txt
This is my cat
  my cat's name is betty
This is my dog
  my dog's name is frank
This is my fish
  my fish's name is george
This is my goat
  my goat's name is adam
$ sed "s/s/S/2" my.txt  #只替换每一行的第2个s
This iS my cat
  my cat's name iS betty
This iS my dog
  my dog's name iS frank
This iS my fish
  my fish'S name is george
This iS my goat
  my goat's name iS adam
$ sed "N;s/This is my \([^\n]*\)\n.*is \(.*\)/\1:\2/g" my.txt
cat:betty
dog:frank
fish:george
goat:adam

进阶部分

这一部分主要是关于 pattern space 和 hold space 的,酷壳的文章中有很好的图例解释,sed 手册里关于这两个概念是这样解释的:

sed 保持有两个数据缓存:当前的 pattern space 和辅助用的 hold space。初始都为空。

sed 对输入的每一行都执行如下的循环,首先,sed 读入一行,并把它放入 pattern space 中,执行命令。命令执行完后,若不是有指定 "-n" 参数则将当前的 pattern space 的内容输出到输出流中,至此完成了关于输入流中一行的循环。

关于这两个数据缓存有几个相关的命令:

  • g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
  • G: 将hold space中的内容append到pattern space\n后
  • h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
  • H: 将pattern space中的内容append到hold space\n后
  • x: 交换pattern space和hold space的内容

几个例子:

$ cat t.txt
one
two
three
$ sed 'H;g' t.txt

one

one
two

one
two
three
$ sed '1!G;h;$!d' t.txt # 反序一个文件的行
three
two
one