本文记录PhD期间出现的shell scripting代码问题以及解决办法.
1. 通过grep出数据并将其储存到变量当中
通过此方法得到的变量,变量后很有可能会有特殊字符,空格,回车之类的。而且很难发现,虽可通过检查字符串长度。 变量本身没什么问题,但如果要把他们加入到运算中,比如if 判断等等,就会出现问题。 解决方案如下:
tr -d '\r' or tr -d '\n' or sed 's/ //g'
例如:
a=$(grep ibrav $prefix.in|cut -d '=' -f 2|sed 's/ //g'|r -d '\r'|tr -d '\n'
具体可参照文章:blog.csdn.net/dingguanyi/…
2. 用rm递归递归删除子目录下所有.o后缀的文件
`find path/ -name *.o |xargs rm -f `#用 xargs 构造参数列表
同理可用于复制目录以及根目录下所有指定文件:
`cp $(find /path/ -type f -name "*.sh") /tmp`
可通过 -maxdepth s设定搜索子目录的深度:
find . -maxdepth 1 -type f -name "xxx"
表示只在当前目录搜索含有"xxx"字符的文件
3. 快速定位匹配字符的行号using awk
Line = $(awk '/String/{print NR}' file.txt)
或者
grep -n "text" file.txt (行数和匹配内容会一起打印出来)
其后可添加各种pipe
4. 用awk将指定行数范围的内容存入数组
Element = ( $(awk 'NR>=start_line && Nr<=end_line {print $1}') file.txt) #注意这个大括号。将元素先行后列的顺序依次存入列表
**#注意当两个行数为变量时,命令如下:**
Element = ( $(awk "NR>=$start_line && Nr<=$end_line {print \$1}") file.txt)
重要: \$ 在这里的作用是在""之下,将 $1 重新转义为awk的字面意思
5. SED模糊匹配删除某行
sed -i "s/^$var.*.txt//" file.txt
可形如这样任意组合
6.简易sed命令
sed -i 'Nd' file.txt #正删
sed -i '$d' #倒删
7. SED 直接显示指定行数范围的内容
sed -n ''$M','$N'p' file.txt
8. sed -i "s/xxx/yyy/"
此命令表示的去替换是 每行 匹配的第一个目标,也就是说所有行的含有xxx的第一个地方都会被替换。
sed -i "s/xxx/yyy/g" 则表示将每行的所有匹配项替换掉
如果只要全文中第一处出现的地方,则需要:
sed -i '0,/pattern/{s/pattern/replacement/}' filename
9. 当使用Sed替换时,中间同时出现转译字符以及变量怎么办-SED的灵活运用
首先要知道''与""分别表示为直接显示以及展开运算并且sed -e s/// filename.txt 可以灵活的添加' '与" "到每个部分上比如:
1. sed -e s/$xxx/$yyy/ filename
2. sed -e s/'$xxx'/$yyy/ filename
3. sed -e 's/$xxx/$yyy/' filename
特别注意一下情况:
sed -e s/\\n.*/\\n$name/ filename
此情况下\\n不需要被展开,但$name需要被展开所以就需要灵活搭配''与""
sed -e 's/\\n.*/\\n'$name'/' filename
在单引号中间再引入单引号即可展开变量。
bash关于提取数字与字母的方法以及变量嵌套的问题
此项工作原本想要批量修改文件名:
所以得分别提取出文件名中数字与字母.
om18.xyz -> 18_om.xyz
a=(`ls|grep [0-9]`)
for ((i=0; i<${#a[*]}; i++ )); do
filename="${a[i]}"
num="${filename//[!0-9]/}"
letters="${filename//[0-9]/}"
注意bash不支持,以下变量嵌套的形式。所以在中间引入了用一个filename的中间变量。
num="${${a[i]}//[!0-9]/}", letters="${${a[i]}//[0-9]/}"
用sed命令匹配指定行并在其下一行进行修改
sed -e "/pattern/{n; s/search/replacement/}"
知识点在于n(next)以及s/p/{n; s/s/r/} 结构的使用
用find递归查找最深处或指定当前路径下的文件夹 比如说我想查找当前路径下递归(最深处)的带数字的文件夹,可以用如下find命令:
find . -name "*[0-9]"
命令可以用于复制、移动、删除等操作十分方便.并且可以使用 -prune -o的命令,避开某些不想搜索的文件夹,
find . -type -d -path './18_rec' -prune -o -name '*[0-9]'
以上命令就可以在递归查找中,排除搜寻18_rec以下的所有文件与文件夹。 如果想要排除多个路径,则可使用以下命令:
find . -type d \( -path './18_rec' -o -path './l_rec' \) -prune -o -name "*[0-9]" -print
注意( -path './18_rec' -o -path './l_rec' ) 的用法以及-prune出现的位置。
sed只修改第一行中第一次匹配的元素
r18_rec.xyz #比如只删除第一个'r'
echo r18_rec.xyz | sed '0,/r/s//'
#0代表第一行,s//此处结构代表把第一次出现的r删除掉
awk过滤某一列大于0的方法
awk -F" " '$1>0{print $1}' file
-F 表示使用分隔符功能, " "表示使用空格作为分隔符, 1>0 即为判断语句第一列中大于0的数据, '{print 1}' 则是打印判断过后的第一列. 要注意的是, awk命令并不能像sed -i 一样在原文件中进行修改. 需要先输出到副本, 再进行覆盖
grep首行内容
grep -m 1 '^' filename
通过rsync备份数据
rsync -av ./* --exclude={'file1','file2'} ./
当需要保持文档目录结构,但又想排除某些文件时候,可以用--exclude={'file1','file2'}的结构来排除不想复制的文件。 尝试过用 find 命令找出这些文件,但是似乎find并不能保持根目录与子目录的结构。
awk 统计行数
awk 'END{print NR}' 统计行数
用awk 如何添加 if 条件
结构: awk 'if(conditions) {print $1,$2,$3...}"text"}' file name
显示当前目录下所以的子目录
ls -d *
ls -v 按值排序显示
注意在-d 后面要加*