一些很有用的 Linux 命令
并行
耗时 5 分半 |
grep
基本用法
Usage: grep [OPTION]… PATTERN [FILE]…
Example: grep -i ‘hello world’ menu.h main.c
字段
-r 遍历某个文件夹,而不是只搜索某个文件
-n 显示行号
搜索整个 OpenFOAM solvers 文件夹,找到所有文件内容包含 LES 的文件
grep -rn LES $FOAM_SOLVERS |
find
基本用法
查找目录:find (查找范围) -name ‘查找关键字’ -type d
查找文件:find (查找范围) -name 查找关键字
搜索默认将在当前目录中开始
查找当前目录下 abort 开头的文件
find ./ -name 'abort*' |
但是上边这个命令会输出子文件夹里边的 abort* 文件。
我只想输出当前目录下的呢?
find . -maxdepth 1 -name abort* |
查找 OpenFOAM solvers 文件夹,找到所有文件名包含 fvPatch 的文件
find $FOAM_SOLVERS -name “*fvPatch*” |
find & rename
find . -type f -name sourcePV -execdir mv sourcePV SourcePV \; |
find & grep
find -name "fvSolution" | xargs grep PBiCGStab |
find & rm
find . -name 'C7H16*' | xargs rm |
这个比较高效 |
删除除了 `C12` 开头以外的其它文件 |
find & sed
找到所有的 *.C *.H 文件,删除行尾空格和 tab |
高级用法
在 Linux 库中搜索文件时,有时会提示没有权限,可以将这些提示重定向到 / dev/null
find -name libgcc.so 2>/dev/null |
对于文件夹
find -name 'C7H16*' | xargs rm -r |
sed
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file] |
常用 OPTION
-i
直接修改文件-r
use extended regular expressions in the script
文件操作
- d 删除
- a 在下一行新增
- i 在上一行插入
- c 以行为单位的取代
- s 替换
操作实例
删除行
删除第一行
sed -i '1d' <filename> |
删除最后一行
sed -i '$d' <filename> |
删除第 N 行
sed -i ‘Nd’
删除 1 到 20 行,Linux 下标是从 1 开始的
sed -i '1,20d' <filename> |
从第 1 行开始, 每隔 2 行删除,即删除 1··3··5··7·· 行。
sed -i 1~2d <filename> |
删除空行
sed '/^\s*$/d' fileName |
删除重复行
awk '!a[$0]++' fileName |
删除文件中含特定字符串(如 abc)的行
这个操作好像不能使用 -i ,只能把结果重定向到一个新的文件 |
删除文件中包含某个关键字开头的所有行
sed -i '/^abc/d' <fileName> |
删除 m 字符结尾的所有行
sed '/m$/d' <fileName> |
删除 x 或者 m 字符结尾的所有行
sed '/[xm]$/d' <fileName> |
替换字符串
sed -r -i 's/被替换字符/替换后的字符/g' <filename> |
如果被替换的字符串中有变量,把最外层的单引号改成双引号
var=300 |
删除某些字符串,即把它替换成空
sed -r -i 's/欲删除字符串//g' <filename> |
删除行尾空格
删除行尾 tab
最对某行进行操作
只对第一行进行操作 |
我定义的函数,用于清理 OpenFOAM 代码
ofFormat () { |
扩展用法
修改软链接对应的真实文件
sed -i --follow-symlinks "操作" settings.csf |
匹配关键字,然后替换下一行的某个关键字
找到 BOUNDARY_INLETTEMPERATURE 的下一行,将 900 替换为 ${temperature} 这个变量的值 |
匹配关键字,然后替换掉整个下一行
将 BOUNDARY_INLETTEMPERATURE 的下一行,修改为 985 |
但是将下一行改为变量,还有问题
sed -i --follow-symlinks '/BOUNDARY_INLETTEMPERATURE/!b;n;c${pressure}' $case/settings.csf |
这个只会将下一行改为 ${temperature}
这个字符串,而不是这个变量的值。
替换多行
|
这里用 python 先生成一个数组,然后输出到文件,然后读取这个文件,读取出来是一列数据,我打算将这一列数据替换掉某个文件中的一列其它数据。
修改文件中包含某个字符串的那一行
适合在脚本中修改 OpenFOAM 的参数设置,不过现在 OpenFOAM 有了自带的脚本来干这件事:foamDictionary
。
!/bin/bash |
这里的 NP 就是所使用的核心数,这里等于 20,对应脚本中的 nodes=2:ppn=10
。
替换某列
把第 79 列替换成空格,这里的 点 表示任意单个字符
sed -i 's/./ /79' <filename> |
同时替换多个
用法
ls *.kg | xargs sed -i 's / 被替串 1 / 新串 1/g;s / 被替串 2 / 新串 2/;s / 被替串 3 / 新串 3/;s / 被替串 4 / 新串 4/' |
举例
但是它不适合替换多个相同的字符,只会替换第一个,因为没有加 g
吗?
匹配所有 .kg 为后缀的文件 |
注意事项
遇到特殊字符,在前边加反斜杠 \
。
空格不算特殊字符,前边不需要反斜杠。
sed ‘s///g’ 与 sed ‘s///’ 的区别
- 加 g,匹配每一行有行首到行尾的所有字符
- 不加 g,匹配每一行的行首开始匹配,匹配到第一个符合的字段,就会结束,跳到下一行
awk
基本用法:
awk -F "用于分隔的符号或者字符串" '{print $ 分隔后你需要的列号}' |
awk 提取某一列字符, 如:
stp=1 dt=1.00e-09 s ord= 1 time=1e-06 ms T_max= 897.7 K T_st= 875.1 K
有一个 log 文件,格式的每一行如上所示,现在需要提取 time 到一个新的文件,代码如下:
grep stp log |awk -F "="'{print $5}'|awk -F"ms"'{print $1}' >time
解释,grep 是获取 log 文件中含有 stp 的所有行。
awk 的主要功能是对列操作,这里按 “等于” 号将每一行分隔为若干列。
然后取第 5 列,获得字符串 1e-06 ms T_max
。
最后将 1e-06 ms T_max
按 ms 分为两列,取第 1 列,即我们需要的 “时间”。
列数为变量时如何使用:
awk -v N=274 '{print $N}' <fileName> |
获取第 274 列数据。
排序
sort [OPTION]... [FILE] |
-g
可以对科学计数法进行从小到大排序-r
逆序
循环、自增操作
for i in `seq 1 100` |
files=`ls Pre*` |
x=0 |
break
跳出循环。continue
命令与 break
命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
字符串判断
参考:https://blog.csdn.net/Mr_LeeHY/article/details/76383091
字符串相同 |
判断大小
整数间的判断
T=999 |
实数间的判断
T=9999.0 |
PS:科学计数法转十进制:
方法 1: printf "%f\n" 3.1188622400e+06
方法 2: echo 3.1188622400e+06 | awk '{printf("%f\n",$0)}'
删除所有文件,except some file
find ./ -name '[^C][^1][^2]*' | xargs rm -rf
# 删除除了 C12
开头以外的其它文件
数组
index
,bash 从 0 开始,zsh 从 1 开始。${abc[i]}
表示数组 abc
的第 i
个分量
来自别的程序输出的数组
timelist=`foamListTimes` |
指定数组并遍历
allThreads=(1 2 4 8 16 32 64 128) |
从文件读取一个数组
mapfile -t List < List_file |
计算最大值
max=`printf '%s\n' "${List[@]}" | awk '$1 > m || NR == 1 { m = $1 } END { print m }'` |
实数运算
整数的加减乘除:
方法一:
b=$((5*5+5-6/2)) |
方法二:
i=5 |
小数点位数
time=0.00015 |
输出:0.0002
保留 4 位小数,后边直接截断,不进行四舍五入。
time=0.00015 |
输出:0.0003
四舍五入,保留 4 位小数。
浮点数的加减乘除:
方法一:
c=$(echo "5.01-4*2.0"|bc) |
例外:c=$(echo "1/1000"|bc)
输出为 0,因为它是小于 1 的小数。如何才能正确输出小数呢?
方法二:
c=$(awk 'BEGIN{print 7.01*5-4.01}') |
例外:我想输出从 0 到 1 之间的等间距小数
for i in `seq 0 10` |
for i in `seq 1 10` |
for i in `seq 1 10` |
修改文件名
先来点简单的操作
增加后缀
find . -type f -exec mv '{}' '{}'.old \; |
增加前缀
for files in $(ls *.png) |
去除前缀
???
去除后缀
???
网址
再来点高级的
将文件名拆分,然后重组,如:
ls fileName | sed -r -n 's/(.*) 分隔字符 (.*)/mv & 替换后的字符 \ 1\2/e' |
举例:
ls chi* | sed -r -n 's/.*tf(.*)/mv & \1/e' # 分隔为 tf 之后部分,全部保留,即保留 tf 后边的字符串 # 原文件名:chi23.0769tf0363to0900Tst2227.kg # 操作后:0363to0900Tst2227.kg # .* 加不加括号的区别在于,加括号后,才计入分隔的部分中; # 如果不加括号,仅仅表示中间还有若干字符,但是不计入分隔后的部分。 ls chi* | sed -r -n 's/(.*)tf.*/mv & \1/e' # 分隔为 tf 之前部分,全部保留,即删去 tf 以及后边的所有字符串。 # 原文件名:chi23.0769tf0363to0900Tst2227.kg # 操作后:chi23.0769 ls chi* | sed -r -n 's/(.*)tf.*.kg(.*)/mv & \1\2/e' # 分隔为 tf 之前,和 .kg 之后 # 这里分隔后,\1 表示 chi23.0769,即前边那个 (.*) 对应的部分,\2 表示'AAA',即后边那个 (.*) 对应的部分。 # 原文件名:chi23.0769tf0363to0900Tst2227.kgAAA # 操作后:chi23.0769AAA ls chi* | sed -r -n 's/(.*)tf(.*).kg(.*)/mv & \1\2\3/e' # tf 和 .kg 把原文件名分隔为三部分,全部保留。 # 原文件名:chi23.0769tf0363to0900Tst2227.kgBBB # 操作后:chi23.07690363to0900Tst2227BBB
字符串模糊匹配与精确匹配
if [["$HOSTNAME" = tetralith*]];then |