SMPCUP2017—Linux命令
-
流重定向命令
>
和>>
,前者是覆盖,后者是追加假如有名为helloworld.py的python script
#!/bin/python3 # -*- coding: UTF-8 -*- print('Hello,world!')
和普通文本文件123.txt
this is 123.txt
在终端命令行中运行
./helloworld.py
,会在终端中输出 Hello,world!
当想要将输入写入文件时,就可以用重定向命令:-
./helloworld.py > 123.txt
,然后123.txt的内容变成下面这样Hello,world!
-
./helloworld.py >> 123.txt
然后123.txt的内容变成this is 123.txt Hello,world!
-
-
查找命令find
find /home -name hello* # 查找home目录下文件名或目录为hello的 find / -name h?m* # 查找根目录下h开头 第二个字符任意 第三个字符是m 后面是任意字符 的文件或目录 find / -size +1000000k # 查找根目录下文件容量大于1000000k的文件
一般情况会用find查找某个文件就行,更多用法详见
man find
-
sed -n '1,$p' file1 > newfile
,输出文件file1的第1~最后一行,然后重定向到文件newfile。如果不加-n,那么会将每一行输出两遍,因为sed本身会输出一遍、p也会输出一遍。
sed s/str1/str2/g file1
,对文件中的每一行进行:将字符串str1替换为str2,结果输出到标准输出(1),加上-i[SUFFIX]则是将替换结果直接写入文件,不会在stdout输出,[SUFFIX]可以用来指定生成的备份文件的后缀,如:sed -i.backup s/str1/str2/g file1
,会生成一个file1.backup文件,内容是被替换前的file1的内容,无需备份的话就直接-i。
sed s/str1/str2/ file1
,相比上一条,没有了g,表现为:只将每行的第一个str1替换为str2。 -
cat file1 | grep regex
cat输出文件file1的内容,grep选取匹配正则表达式regex的所有行
grep -a
处理二进制文件。本次比赛选取blogs时会遇到’Binary file matches’的报错,加上-a即可解决grep -n
可以列出行号grep -w
精确匹配。比如我们想选取文件中开头包含数字’152’的行,如果只用grep ‘152’,就会
把开头是11152/15277/15288等所有包含152的选出来, 改成grep -w '152’后,就只会选取是’152’的,
不会出现’11152’这种的,再改成grep -w ^‘152’ 就是只选去行开头是’152’的行
-
sort file1
和uniq file1
sort可以用来对文件排序。
sort -k 2 -t ' '
以空格为分隔符,以第二列为基准,对文件排序sort -r
默认是升序排序,加上-r选项是降序排序
uniq用来对文件去重。
-
awk
cat file1 | awk '{print $2}'
输出文件file1的第二列。要求文件内容每行有相同分隔符。cat file1 | awk -F ' ' '{print $2}'
以空格为分隔符提取出文件的第二列。cat ccc.txt | awk '{for(i=1;i<=78;i++) if(条件) {printf$i" "; if(条件) printf"";}}'
awk亦是一门编程语言,语法类似于C,相比于其他命令有更强大的处理能力。 -
paste
paste -d ' ' file1 file2
将文件file1和file2 以空格为分隔符 横向拼接起来 (’-d’选项可指定分隔符,默认是制表符)cat file2 >> file1
将file2的内容贴到file1后面,即实现纵向拼接。 (重定向一定要用’>>’,用’>'会覆盖了file1的内容) -
bash script
bash脚本约等于一堆命令的组合+程序语句
#!/bin/bash :<<BLOCK # 找发博客的记录 FILENAME=(../../../SMPCUP2017ValidationSet/SMPCUP2017_ValidationSet_Task02_transencoding.txt) while read LINE do if cat /mnt/windows_G/DataMining/SMPCUP2017DATACorpus/2_Post.txt | grep -a ${LINE} >> Task02_Validation_user_Post.txt then echo "Find:"${LINE} fi done < $FILENAME BLOCK :<<BLOCK # 提取出发的博客 FILENAME=(temp2.txt) while read LINE do uid=${LINE:0:8} did=${LINE:9:8} if doc=`cat ../../../BlogContent_100k_split/Blog04.txt | grep -a $did` then echo "Find:"${did} echo ${uid} ${doc} >> Task02_Validation_Post_blogs.txt else echo ${LINE} >> temp3.txt fi done < ${FILENAME} BLOCK # 将每个用户各自发的博客写在一起 # 这块功能理论上在上一块注释中可以直接实现 FILENAME1=(../../../SMPCUP2017ValidationSet/SMPCUP2017_ValidationSet_Task02_transencoding.txt) while read LINE1 do touch ./Validation_each_user_Post_blogs/${LINE1:0:8}_post_blogs.txt done < ${FILENAME1} FILENAME=(Task02_Validation_Post_blogs_sort.txt) while read LINE do uid=${LINE:0:8} doc=${LINE:18} echo ${doc} >> ./Validation_each_user_Post_blogs/${uid}_post_blogs.txt done < ${FILENAME} echo $SECONDS
- 开头的
#!/bin/bash
指定用哪个解释器执行脚本 - bash中单引号中的字符串相当于python中的raw string,即所有字符都是原义,
双引号中才可以有转义字符;单引号中不可以转义单引号 - FILENAME存放文件名的变量,只存放一个文件名的话,用圆括号/单双引号都行
- 对变量的赋值可以直接进行,使用变量要加’$’。比如: LINE=‘U0002100’是赋值,
想要使用变量 输出LINE, 就是echo ${LINE}
。
使用变量时加上’{}‘花括号是个好习惯。
${LINE:1:5} 表示对变量LINE,从下标1开始,取五个字符,即’00021’ - bash中进行文件的读取,也是本次比赛中常用的操作
# 釜底抽薪式的while读取文件 FILENAME=() while read LINE # read还可以用于读取标准输入,类似python的input() do echo ${LINE} # 输出每一行 done < ${FILENAME}
- if statements
if conditions then action1 action2 else action3 fi
bash中的if语句,else后面为空的话,就不要写else,结束用if的倒写fi。
若conditions执行成功,则执行then后面的语句。
每条命令执行完后都有返回码($?),可以用echo $?
来查看上条命令执行后的结果,返回码为0
则表示执行成功
如上面大段代码块中的if cat file | grep -a regex >> file2
,只有找到regex匹配的行并写入file2,这条cat语句的返回码才为0,
如果没找到匹配的行,那返回码就不为0bash中if语句的条件有多种形式,和其他语言的表示不太一样,具体用时请多查看资料
- 开头的