SYYANI's BLOG

一些唠叨

shell批量操作指南

产生需求:linux环境下对同一文件夹下同一格式的文件批量处理
———使用ffmpeg抽取mp4视频文件中的音频保存为m4a格式
需要对文件夹所有文件进行操作,故关联到批量重命名命令

1
2
3
4
5
6
7
8
9
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for i in `ls|grep glyphicons`
do
newName=`echo $i |cut -d _ -f3`
mv $i $newName
done
IFS=$SAVEIFS

上述代码实现的功能是对文件名形似 glyphicons数字_字符串.png 的文件去除斜体的部分的实现,参考 cut 手册知道 -d 参数用于自定义分隔符,例如上述文件名中存在两处 “__” 下划线,可被分隔符分为3块,配合 -f 参数使用选择被划分的第三块区域,实现目的。
回到需求,命令涉及到对文件后缀名的更改,需要获取文件名中去除后缀名的部分作为新文件的标识,所以 -d 可搭配 “.” 使用 ,再选取合适的划分区域作为 -f 的参数即可,注意文件名中可能会出现 “.” 标识符,故取 -f1 取第一部分作为文件名前缀满足标识需求。
例:抽取example.mp4文件中的音频保存为example.m4a
对单一文件通过ffmpeg工具实现:ffmpeg -i example.mp4 -vn -y -acodec copy example.m4a
则批量处理方法如下:

1
2
3
4
5
6
7
8
#!/bin/bash
for i in `ls|grep mp4`
do
name=`echo $i |cut -d . -f1`
suffix='.m4a'
newName=$name$suffix
ffmpeg -i $i -vn -y -acodec copy $newName
done

但是上述方法没有考虑到文件名中包含空格的情况,作如下处理即可

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for i in `ls|grep mp4`
do
name=`echo $i |cut -d . -f1`
suffix='.m4a'
newName=$name$suffix
ffmpeg -i $i -vn -y -acodec copy $newName
done
IFS=$SAVEIFS

补:chmod a+x example.sh 赋予文件可执行权限

wget指南

产生需求:linux环境下下载ftp网页下指定文件夹的所有文件
使用wget 命令可以完成

1
2
wget -r -np -nH --cut-dirs=8 -R index.html* \
https://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15418-s20/www/code/rec_04/mvmul/

Solution:
wget -r -np -nH --cut-dirs=3 -R index.html http://hostname/aaa/bbb/ccc/ddd/
Explanation:

  • It will download all files and subfolders in ddd directory
  • -r : recursively 指明是对文件夹的操作
  • -np : not going to upper directories, like _ccc/… _不保留上层文件夹
  • -nH : not saving files to hostname folder 不保留ftp服务器名字的文件夹
  • --cut-dirs=3 : but saving it to ddd by omitting first 3 folders aaa, bbb, _ccc _指定下载目的文件夹的层次
  • -R index.html : excluding index.html files 排除_index.html_文件
  • -a pdf only download PDF files** 只下载pdf文件**
  • -e robots=off if there is a robots.txt file disallowing the downloading of files in the directory, this won’t work. In that case you need to add 不遵守robots协议

lldb调试tips

  1. 需要查看一个int*类型数组的内容的某段范围,用到lldb调试。

    例如int* a[8],默认 p a 指令只会输出a[0]的值,或者 p a[i] 格式,降低效率

    在gdb中如下,即 [start] 中放入起始位置, @ 符号后接长度

    1
    display a[0]@10

    lldb中需要先设置 int* 类型的默认展示范围,之后打印即可。

    1
    2
    type summary add -s "${var[0-10]}" "int *"
    point a
  2. 需要打印一个string的全部内容,gdb设置的string超出200的不予显示

    1
    set print elements 0

新博客指南

本博客采用GitHub仓库提供的Issue和Actions发布。

Github Issues 本身可以作为一个内容管理的工具,例如借助插件可以将其用于托管博客的评论,它支持Markdown语法,可以粘贴带图,操作上的open和close状态可以对应草稿和发布…非常酷!

image-20230126135808673

How?

这一整个流程,可以简化如下:

  1. 我有一个私有仓,syyani/blog,我在里面码字

  2. 我有一个公开仓,syyani/syyani.github.io,用来发布 GitHub Pages

  3. 在私有仓里,我做了一个 sync workflow。只要 Issues 有任何变化,就触发公开仓的另一个 deploy workflow

    image-20230126140107271

    私有仓yml配置如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    name: Sync posts

    on:
    issues:
    workflow_dispatch:

    permissions:
    contents: read

    concurrency:
    group: sync
    cancel-in-progress: true

    jobs:
    sync:
    runs-on: ubuntu-latest
    steps:
    - name: Sync
    run: gh workflow run deploy.yml
    env:
    GH_REPO: SYYANI/SYYANI.github.io
    GH_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
  4. 公开仓的 deploy workflow 作用很简单,就是拉取私有仓的 Issues,生成 posts,然后生成最终 HTML,部署image-20230126140212014

    公开仓的 deploy workflow,大家自己也可以看到:deploy.yml。它的另一个关键是 sync.mjs 这个用来拉取 Issues 并生成 posts 的脚本。

    如果你想把这套流程用到你自己的博客,你需要开一个 Personal Access Token[^👇] 分别加到两个仓库的 Secrets 里(名称为 DEPLOY_TOKEN)。并且对应更改这两个 workflow 里的 GH_REPO 变量。

    [^👇]:首先进入GitHub的设置页面:依次是 Settling -Developer Settling - Personal access tokens - Token(classic) - Generate new token(classic) ,由于只是用来同步仓库,只用给repo权限即可。

Proudly powered by Hexo and Theme by Hacker
© 2023 SYYANI