美文网首页
Shell命令行Tips整理【持续更新】

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

作者: 吃远 | 来源:发表于2018-12-17 10:55 被阅读0次
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很长,中间丢弃几帧也是可以接受的。

相关文章

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

    1. mkdir -p:递归创建文件夹 应用举例:image.png参考: https://stackoverfl...

  • tips 持续更新

    在swift中的变量一般分为三种: swift - 类在数组中的写法 swift - 状态栏隐藏方法 xcode ...

  • android 常用小知识点 tips (二)

    android 常用小知识点 tips (一)android 常用小知识点 tips (二) 持续更新中.... ...

  • iOS Tips(持续更新)

    1、网络请求封装采用类方法还是单例模式?2、extern字符串常量,宏定义字符串常量怎么选?const常量有数据类...

  • CSS tips(持续更新...)

    处理文字溢出省略号代替: 使用box-shadow,制作四周阴影: 移动端viewport “三件套” : 让元素...

  • Swift Tips(持续更新)

    通过字符串创建类对象 在swift中打印对象时,会发现在类型前面总会有命名空间 +.+ 类名; 在swift中用字...

  • Swift Tips(持续更新)

    1、NSMutableAttributedString to String 2、swift中的交换元素使用swif...

  • iOS Tips【持续更新】

    1.DSYM在哪?使用Finder前往路径 2.UITextField的placeholder属性修改 3.全局替...

  • py1

    名字解释: 【shell】 传统意义上的shell指的是命令行式的shell。命令行式shell(Command ...

  • Android Tips

    Android Tips将持续更新 Mac Mac系统下,打开Android SDK Manager Androi...

网友评论

      本文标题:Shell命令行Tips整理【持续更新】

      本文链接:https://www.haomeiwen.com/subject/efjqkqtx.html