数据库有“增、删、查、改”几个动作,而在 Linux 下生活的人,莫外乎也经常有这几个操作。
在指定目录下找文件,常用 find 命令。以下是 man 手册对 find 命令进行功能性的解释:
find - search for files in a directory hierarchy
比如,要去 kernel/driver/ 目录下找一个名字叫 led-class.c 文件:
$ find ./kernel/msm-3.18/drivers/ -name led-class.c
./kernel/msm-3.18/drivers/leds/led-class.c
或者找到所有头文件(以 .h 结尾的文件)
find ./kernel/msm-3.18/drivers/ -name *.h
这样,就可以找到 kernel/msm-3.18/drivers/ 目录下所有的头文件了(* 表示通配符,意思是匹配所有以 .h 结尾的文件)。
要找一个文件或者多个文件里面某一个指定的字符串,常用 grep 命令。比如找出 kernel/msm-3.18/drivers/leds/led-class.c 文件中所有的 “leds_class”字符串:
$ grep -rsn "leds_class" kernel/msm-3.18/drivers/leds/led-class.c
25:static struct class *leds_class;
224:static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
233: led_cdev->dev = device_create_with_groups(leds_class, parent, 0,
303: leds_class = class_create(THIS_MODULE, "leds");
304: if (IS_ERR(leds_class))
305: return PTR_ERR(leds_class);
306: leds_class->pm = &leds_class_dev_pm_ops;
307: leds_class->dev_groups = led_groups;
313: class_destroy(leds_class);
上面即可列出,leds_class 这个字符串,分别在该文件的第 25、224、233、303、304、305、306、307、313 行出现。
现在是找 leds_class 这个字符串在 led-class.c 文件中出现的位置。那现在换一个场景,找 leds_class 这个字符串出现在哪些文件中,可以使用如下方式:
$ find ./kernel/msm-3.18/drivers/ -name *.c | xargs grep leds_class
./kernel/msm-3.18/drivers/leds/led-class.c:static struct class *leds_class;
./kernel/msm-3.18/drivers/leds/led-class.c:static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
./kernel/msm-3.18/drivers/leds/led-class.c: led_cdev->dev = device_create_with_groups(leds_class, parent, 0,
./kernel/msm-3.18/drivers/leds/led-class.c: leds_class = class_create(THIS_MODULE, "leds");
./kernel/msm-3.18/drivers/leds/led-class.c: if (IS_ERR(leds_class))
./kernel/msm-3.18/drivers/leds/led-class.c: return PTR_ERR(leds_class);
./kernel/msm-3.18/drivers/leds/led-class.c: leds_class->pm = &leds_class_dev_pm_ops;
./kernel/msm-3.18/drivers/leds/led-class.c: leds_class->dev_groups = led_groups;
./kernel/msm-3.18/drivers/leds/led-class.c: class_destroy(leds_class);
不过这个方式,个人认为比较鸡肋,还不如直接这样:
grep -rn leds_class ./kernel/msm-3.18/drivers/
其实这个就是两个或者多个命令的组合,前一个命令的输出是后一个命令的输入,这个传递过程中,需要一个媒介来将前一个命令的输出,传递到后一个命令的输入。此时使用 xargs 可以解决这个问题。比如,找到 led-class.c 文件并删除它,我们常规的两个命令操作如下:
$ find ./kernel/msm-3.18/drivers/ -name led-class.c
./kernel/msm-3.18/drivers/leds/led-class.c
$ rm -rf ./kernel/msm-3.18/drivers/leds/led-class.c
但如果想偷懒,一步到位呢?使用 xargs 就可以达到该要求:
$ find ./kernel/msm-3.18/drivers/ -name led-class.c | xargs rm -rf
$ git status ./kernel/msm-3.18/drivers/
Changes not staged for commit:
(use "git add/rm ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
deleted: kernel/msm-3.18/drivers/leds/led-class.c
no changes added to commit (use "git add" and/or "git commit -a")
确认是已经删除了。(当然,没事别随意删除,尤其是在没有版本控制或者备份的情况下^_^)
比如将某个目录及其子目录下的 N 个文件中的字符串 A 替换成字符串 B,使用 sed 可以顺利完成。比如将 frameworks/ 目录下所有文件中的 leds 字符串替换成 sdel 字符串。先列一下有哪些文件:
$ grep -rn leds ./frameworks/
./frameworks/native/cmds/dumpstate/dumpstate.cpp:915: dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness");
./frameworks/native/cmds/dumpstate/dumpstate.cpp:917: dump_file(NULL, "/sys/class/leds/button-backlight/brightness");
./frameworks/native/cmds/dumpstate/dumpstate.cpp:919: dump_file(NULL, "/sys/class/leds/keyboard-backlight/brightness");
./frameworks/native/cmds/dumpstate/dumpstate.cpp:921: dump_file(NULL, "/sys/class/leds/lcd-backlight/als");
./frameworks/native/cmds/dumpstate/dumpstate.cpp:923: dump_file(NULL, "/sys/class/leds/lcd-backlight/registers");
./frameworks/native/services/inputflinger/tests/InputReader_test.cpp:325: KeyedVector leds;
./frameworks/native/services/inputflinger/tests/InputReader_test.cpp:431: device->leds.add(led, initialState);
./frameworks/native/services/inputflinger/tests/InputReader_test.cpp:436: return device->leds.valueFor(led);
./frameworks/native/services/inputflinger/tests/InputReader_test.cpp:658: return device && device->leds.indexOfKey(led) >= 0;
./frameworks/native/services/inputflinger/tests/InputReader_test.cpp:664: ssize_t index = device->leds.indexOfKey(led);
./frameworks/native/services/inputflinger/tests/InputReader_test.cpp:666: device->leds.replaceValueAt(led, on);
./frameworks/base/tests/StatusBar/src/com/android/statusbartest/ToastTest.java:87: String text = "freq=" + readFile("/sys/class/leds/red/device/grpfreq")
./frameworks/base/tests/StatusBar/src/com/android/statusbartest/ToastTest.java:88: + "\npwm=" + readFile("/sys/class/leds/red/device/grppwm");
开始替换吧:
$ sed -i 's/leds/sedl/g' `grep -lrn leds ./frameworks/`
注意,前面是单引号(’ ‘),后面是键盘波浪线(~)位置的斜点(`)。
看一下其中一个文件的修改点:
--- a/frameworks/base/tests/StatusBar/src/com/android/statusbartest/ToastTest.java
+++ b/frameworks/base/tests/StatusBar/src/com/android/statusbartest/ToastTest.java
@@ -84,8 +84,8 @@ public class ToastTest extends TestActivity
new Test("Read lights") {
public void run()
{
- String text = "freq=" + readFile("/sys/class/leds/red/device/grpfreq")
- + "\npwm=" + readFile("/sys/class/leds/red/device/grppwm");
+ String text = "freq=" + readFile("/sys/class/sedl/red/device/grpfreq")
+ + "\npwm=" + readFile("/sys/class/sedl/red/device/grppwm");
mToast1 = Toast.makeText(ToastTest.this, text, Toast.LENGTH_SHORT);
mToast1.show();
}
已经将 leds 修改为 ldes 了。下面对 s/leds/sedl/g 稍作解释:
s/原字符串/目的字符串/全局替换
这个方法在 vim 里面也可以使用的。
哎,蛋疼!