Shell命令行Tips整理【持续更新】

1. mkdir -p:递归创建文件夹

  • 更新: mkdir -p 还包含了对文件路径的检查,同下面代码,但是显然更加elegant:
if [ ! -d dirName ]; then
    mkdir dirName;
fi

2. sort --random-sort: 随机选取元素
  • 应用举例:
    ls target_dir | sort --random-sort | head -n 100 | xargs -i cp -v target_dir/{} .
    在某个文件夹中随机抽取100个文件,并拷贝到当前文件夹
3. list files without specific pattern 列出文件时排除某些模式

动机:
  实现该功能的动机是在ls或者copy时想要排除掉文件夹。在网上找了下,有两个比较好的方案:
3.1. ls -I"xx"ls --ignore="xxx"
这是最直接的方法,可以去除某种特定pattern。优点是简洁易用,缺点是无法直接排除所有dir,只能通过dir名字进行排除。

  • 应用举例:


    image.png

注意,这里-I--ignore是一回事,前面是简写而已(类比argparse)。

3.2. find . -maxdepth 1 -type -f -not -name 't_*'

  这个命令非常好用,有必要详细记录下。可以同时exclude文件夹以及不想要的pattern,还可以选择recursive的深度。

  • -maxdepth 指定递归深度。设为1则只返回当前路径的结果(不包含子文件夹内的文件)
  • -type f 只返回files,不返回directories或者其他的device nodes等等
  • -not -name组合使用,可以排除掉某些不想要的名字
image.png
4. #!/bin/bash: zsh下执行shell脚本的一个坑

  之前在bash下写shell脚本,一直觉得#!/bin/bash没啥用,就经常不写,有时候写的话还老写不完整。最近在虚拟机用zsh执行一个shell脚本,显示不支持其中if语句后面的"[["。为了解决这个问题搜索了很久,以为是bash的环境变量没添加到zshrc中。后来还发现zsh原来有自己的一套shell语句规范,和bash稍有不同。但是这都不是我要的答案。

  最后终于找到问题所在,其实zsh不存在不兼容bash脚本的问题,只需要在脚本头部添加一句#!/bin/bash,要求使用bash执行当前脚本就行了。我当时写错了写成#/bin/bash,结果一直报错....
参考: https://unix.stackexchange.com/questions/15950/how-to-list-files-without-directories-and-filter-by-name-ls-options

5. 关于前缀和后缀(文件名或者command line output)
  • 5.1 批量修改文件名(加前缀或者后缀)
awk '$0="prefix"$0' file > new_file

简单而强大。有时间要把awk好好学一学。

  • 5.2 终端命令行

  场景:假如我有两个文件夹,一个叫flowers,存放许多花的照片,包含不同品种;另一个叫masks,存放每图片对应的前景mask。现在我进入放置花的文件夹中随便挑了若干张我喜欢的,然后把它们拷贝到其他文件夹。现在我想把masks中对应的图片也挑出来,放到一起(显然对应的flower图片和mask图片之间有部分相同的pattern)。我想用一句shell命令完成这个操作。

  (注:某一对图片的名称分别为:image_xxx_0001.png 和 mask_xxx_0001.png,xxx为类别名称)

ls | grep png | cut -d _ -f 2,3 | sed 's/.*/mask_&/' | xargs -i cp masks/{} .

第一部分很简单,通过grep筛选出png文件,用cut -d -f找到mask和flower文件夹中相同的pattern;第二部分批量加前缀 “mask_”。即找到了masks文件夹中对应的文件。

此外, 可以用cut -d _ -f 2-返回后面的所有字符。

  • sed的灵活用法:
ls | grep txt | sed 's/.*/prefix&suffix/'
6. 强大的awk
6.1 简介:

   awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。 awk的创建者将其定义为“样式扫描和处理语言”,允许我们创建简短的程序,读取输入文件、为数据排序、处理数据、对输入文件执行计算以及生成报表等。

6.2 使用方法:
awk '{pattern + action}' {filename}

注意,花括号不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。pattern就是要表示的正则表达式,用斜杠括起来。

  • awk最基本的功能是在文件或字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

  • awk通常以文件的一行作为处理单位。

6.3 实例学习
6.4 实用的场景举例
    1. 将一个csv文件的所有浮点数转换为整数(该文件中既包含整数形式也有部分浮点数形式)


      bounding box csv文件.png
awk 'BEGIN {FS=" +|,";} {printf("%s','%.0f %.0f %.0f %.0f\n", $1,$2,$3,$4,$5);}' train_labels.csv

注意printf中要格式化输出空格,直接用空格即可。不需要用\0之类的

转换结果


    1. 用于获取某个路径下所有标注文件(xml)中包含了哪几种类别
 ls $1 | awk -v var=$1 '/xml/{print "cat "var"/"$0" | grep /name"}' | bash | awk -F '>|<' '{print $3}' | uniq | tr "\n" " " > $1/ClassNames.txt

  解释:
①$1为包含标注图像数据的路径
②在awk语句中使用shell变量:参考:
https://stackoverflow.com/questions/19075671/how-do-i-use-shell-variables-in-an-awk-script
③一个典型的VOC类型的物体检测标注xml文件:

VOC xml文件示例

grep /name提取出包含标记类别的行
④第二个awk用于从<name>hand</name>中提出hand。感觉应该有更简练的提取方法。
tr "\n" " "用于将行形式的输出转换为列形式


7. 拷贝目录
  • 场景:有时候在远程服务器上工作时,想要拷贝或者是远程拷贝一个目录给同事,但是可能同事比较在意这个目录结构以及脚本(不要小看了“结构”,很多组织有序的文件夹就是一个Python module~),但是不在意目录里面的数据集(可能有多个位置存放数据,且占空间较大)。也就是说,我希望拷贝整个目录结构,同时exclude掉不想要的pattern,如*.jpg,或者一些较大的模型权重,如.h5,但是又保留他们各自所在的子文件夹,以便让我的同事知道这个文件夹应该放数据集,那个文件夹应该放权重。如何快速做到这些?

  • 先考虑一个稍微简单但是常用点的,获取某个路径所有文件夹名字并在目标路径中创建这些文件夹。如果是以前,我应该会这么做(复习下数组):
dirList=(`find . -maxdepth 1 -type d -not -name "." | awk -F '/' '{print $2}' | tr "\n" " "`)
for item in ${dirList[@]};do mkdir $TARGET/$item;done

为了给同事一个干净的文件夹,我不想拷贝以下内容:1.jpg文件,2. .h5文件,3. pycahce文件夹 4. 一些错误文件类似events.out.tfevents.1548346771.fpc

  • 现在看看我的这行命令:
rsync -av --progress toolkit_yolo_map tst_destination 
--exclude="*.jpg" --exclude="*.xml" --exclude="*.h5" 
--exclude="__pycache__" --exclude="result/*" --exclude="*events*"

看起来是不是很长?再仔细看下,有效的就三个部分,原目录,目标目录,多个exclude模式,极其简单。再看看效果:

$ tree tst_destination
tst_destination
└── toolkit_yolo_map
    ├── 2007_train.txt
    ├── 2007_val.txt
    ├── before_training.sh
    ├── boom.sh
    ├── data
    │   ├── augDataset
    │   │   ├── aug_labels.csv
    │   │   ├── clean
    │   │   └── display
    │   ├── create_aug_dataset.sh
    │   ├── DataAugmentation.py
    │   ├── legacy
    │   │   ├── arange_auged_label.sh
    │   │   └── train_labels.csv
    │   ├── test_dataset
    │   ├── train_dataset
    │   ├── train_labels.csv
    │   └── train_xml
    ├── finetune_baseline_on_aug_dataset.py
    ├── font
    │   ├── FiraMono-Medium.otf
    │   └── SIL Open Font License.txt
    ├── kmeans.py
    ├── logs
    │   └── confidente_model
    │       ├── finetune.log
    │       ├── loss_curve.png
    │       └── train_val_loss.csv
    ├── model_data
    │   ├── coco_classes.txt
    │   ├── my_classes.txt
    │   ├── new_yolo_anchors.txt
    │   ├── tiny_yolo_anchors.txt
    │   ├── voc_classes.txt
    │   └── yolo_anchors.txt
    ├── plot_training_curve.py
    ├── README.md
    ├── result
    ├── src
    │   ├── dataConfig.sh
    │   ├── kmeans.py
    │   ├── step_1_process_data.py
    │   ├── step_2_mv_data.py
    │   ├── step_3_voc_annotation.py
    │   ├── step_4_train.py
    │   ├── step_5_yolo_video.py
    │   └── yolo.py
    ├── tmp_data
    │   ├── augDataset
    │   │   ├── aug_labels.csv
    │   │   ├── clean
    │   │   └── display
    │   ├── create_aug_dataset.sh
    │   ├── legacy
    │   │   ├── arange_auged_label.sh
    │   │   └── train_labels.csv
    │   ├── test_dataset
    │   ├── train_dataset
    │   ├── train_labels.csv
    │   └── train_xml
    ├── train_finetune.sh
    ├── VOCdevkit
    │   └── VOC2007
    │       ├── Annotations
    │       ├── ImageSets
    │       │   └── Main
    │       │       ├── test.txt
    │       │       ├── train.txt
    │       │       └── val.txt
    │       └── JPEGImages
    ├── yolo3
    │   ├── __init__.py
    │   ├── model.py
    │   └── utils.py
    └── yolo_anchors.txt
  • 结束。上面的Stack Overflow中有很多其他有趣的答案,非常值得一看。
8. 记mac下终端命令行下的一个小坑(对比linux命令行)
  • 环境: ubuntu和mac下均为zsh命令行
  • 今天在mac和ubuntu上执行同一个脚本时发现出现了不一样的结果,仔细追究了一下,原来是mac和linux上的grep命令有一个小小的差异。首先给出一段我正在预处理的文本:
[Chiyuan info] VehicleInfo: throttle: 27.756, brake: 14.633
  Serializer frame count: 0
[Chiyuan info] Current Position: ( 395855.807, 3416411.559, 16.373 )
[Chiyuan info] Current Heading: -0.590
[Chiyuan info] VehicleInfo: throttle: 27.756, brake: 14.644
  Serializer frame count: 0
[Chiyuan info] Current Position: ( 395855.807, 3416411.559, 16.373 )
[Chiyuan info] Current Heading: -0.590
[Chiyuan info] VehicleInfo: throttle: 27.768, brake: 14.644
  Serializer frame count: 0
[Chiyuan info] Current Position: ( 395855.807, 3416411.559, 16.373 )
[Chiyuan info] Current Heading: -0.590
[Chiyuan info] VehicleInfo: throttle: 27.768, brake: 14.627
^[[0;31mE0710 14:32:40.377712  2032 localization_util.cpp:337] [ERROR] [GetCarPoseFromWindow] input timestamp behind of pose window end[input time, window end] : 11976256, 1562740358270000128
^[[m^[[0;31mE0710 14:32:40.378336  2032 localization_querier.cpp:286] [ERROR] [LOCALIZATION] car pose unusable please check from_timestamp_ns
^[[mlidarfreespace carpose error: 11976256
[Chiyuan info] Current Position: ( 395855.807, 3416411.559, 16.373 )
[Chiyuan info] Current Heading: -0.590
[Chiyuan info] VehicleInfo: throttle: 27.756, brake: 14.627
[Chiyuan info] Current Position: ( 395855.909, 3416411.493, 16.374 )
[Chiyuan info] Current Heading: -0.587
[Chiyuan info] VehicleInfo: throttle: 27.756, brake: 14.624
[Chiyuan info] Current Position: ( 395855.935, 3416411.477, 16.374 )
[Chiyuan info] Current Heading: -0.586
[Chiyuan info] VehicleInfo: throttle: 27.756, brake: 14.624
  Serializer frame count: 1
[Chiyuan info] Current Position: ( 395855.935, 3416411.477, 16.374 )
[Chiyuan info] Current Heading: -0.586
[Chiyuan info] VehicleInfo: throttle: 27.756, brake: 14.604
  Serializer frame count: 1
  Serializer frame count: 1
[Chiyuan info] Current Position: ( 395855.935, 3416411.477, 16.374 )
[Chiyuan info] Current Heading: -0.586
[Chiyuan info] VehicleInfo: throttle: 27.659, brake: 14.604
^[[0;31mE0710 14:32:40.430655  2032 localization_util.cpp:337] [ERROR] [GetCarPoseFromWindow] input timestamp behind of pose window end[input time, window end] : 11976256, 1562740358350000128
^[[m^[[0;31mE0710 14:32:40.431396  2032 localization_querier.cpp:286] [ERROR] [LOCALIZATION] car pose unusable please check from_timestamp_ns
^[[mlidarfreespace carpose error: 11976256
[Chiyuan info] Current Position: ( 395855.935, 3416411.477, 16.374 )
[Chiyuan info] Current Heading: -0.586
[Chiyuan info] VehicleInfo: throttle: 27.659, brake: 14.604
[Chiyuan info] Current Position: ( 395855.935, 3416411.477, 16.374 )
[Chiyuan info] Current Heading: -0.586
[Chiyuan info] VehicleInfo: throttle: 27.475, brake: 14.604
[Chiyuan info] Current Position: ( 395855.961, 3416411.460, 16.374 )
[Chiyuan info] Current Heading: -0.585
[Chiyuan info] VehicleInfo: throttle: 27.475, brake: 14.583

然后对这个log文件进行同样的处理:cat test.log | grep -A3 frame:
  ubuntu上给出的结果:

Ubuntu命令行grep -A3

Mac命令行grep -A 3

  • 简而言之,对于多个“重复的”匹配结果,ubuntu中的grep -A会把它们视为一个group(假如两个"--"中间的内容为一个group的话);而mac中的grep -A会将每一个匹配结果视为一个group。

  • 扩展:在ubuntu上我可以通过如下面命令实现该log的简单去重(Mac上无法实现):

cat test.log | grep -A3 frame | grep -B4 "\-\-"
  • 结果如下:


    log字符串段落整理

  注意到这样就能把每一帧对应的log取出来了。虽然最后一帧由于下面没有"--"分隔符没有获取到,但是由于log很长,中间丢弃几帧也是可以接受的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容