第三章 以檔案之名
生成任意大小的檔案
$ dd if=/dev/zero of=junk.data bs=1M count=1
記錄了1+0 的讀入
記錄了1+0 的寫出
1048576位元組(1.0 MB)已複制,0.735955 秒,1.4 MB/秒
查找并删除重複檔案
條件:删除那些雖然名字不同但内容一模一樣的檔案
通過檔案内容來識别他們,校驗和是依據檔案内容來計算的,内容相同的檔案自然就生成想通的校驗和
通過比較校驗和來删除重複檔案
書本代碼有誤,補充如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<code>#!/bin/bash</code>
<code>ls</code> <code>-lS | </code><code>awk</code> <code>'BEGIN{</code>
<code>getline;getline;</code>
<code>name1=$9;</code>
<code>size=$5</code>
<code>}</code>
<code>{</code>
<code>name2=$9;</code>
<code>if</code> <code>(size==$5)</code>
<code>"md5sum $name1"</code> <code>| getline;csum1=$1;</code>
<code>"md5sum $name2"</code> <code>| getline;csum2=$1;</code>
<code>if</code> <code>(csum1==csum2)</code>
<code>print name1;</code>
<code>print name2;</code>
<code>};</code>
<code>size=$5;</code>
<code>name1=name2;</code>
<code>}' | </code><code>sort</code> <code>-u > duplicate_files</code>
<code>cat</code> <code>duplicate_files | </code><code>xargs</code> <code>-I {} md5sum {} | </code><code>sort</code> <code>| </code><code>uniq</code> <code>-w 32 | </code><code>awk</code> <code>'{ print $2 }'</code> <code>| </code><code>sort</code> <code>-u > duplicate_sample</code>
<code>echo</code> <code>Removing..</code>
<code>comm</code> <code>duplicate_files duplicate_sample -2 -3 | </code><code>tee</code> <code>/dev/stderr</code> <code>| </code><code>xargs</code> <code>rm</code> <code>-f</code>
<code>echo</code> <code>Removed duplicates files successfully.</code>
<code>rm</code> <code>duplicate_sample duplicate_files</code>
以不同的使用者運作可執行檔案
原理:有一個叫做setuid的特殊檔案權限,它允許其他使用者以檔案所有者的身份來執行檔案
chown root.root execu_file
chown +s execu_file
./execu_file
這個檔案事實上每次以超級使用者來運作
setuid的使用不是無限制的,它隻能應用在linux ELFG格式二進制檔案上,二不能用于腳本
建立檔案不可修改
限制:一旦檔案呗設定為不可修改,任意使用者包括超級使用者都不能删除檔案,除非其不可修改的屬性被移除
通過檢視/etc/mtab檔案,很容易找出所有挂載分區的檔案系統類型
cat /etc/mtab
/dev/sda1 / ext4 rw,errors=remount-ro 0 0
proc /proc proc rw,noexec,nosuid,nodev 0 0
sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
none /sys/fs/cgroup tmpfs rw 0 0
none /sys/fs/fuse/connections fusectl rw 0 0
none /sys/kernel/debug debugfs rw 0 0
none /sys/kernel/security securityfs rw 0 0
udev /dev devtmpfs rw,mode=0755 0 0
devpts /dev/pts devpts rw,noexec,nosuid,gid=5,mode=0620 0 0
tmpfs /run tmpfs rw,noexec,nosuid,size=10%,mode=0755 0 0
none /run/lock tmpfs rw,noexec,nosuid,nodev,size=5242880 0 0
none /run/shm tmpfs rw,nosuid,nodev 0 0
none /run/user tmpfs rw,noexec,nosuid,nodev,size=104857600,mode=0755 0 0
binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,noexec,nosuid,nodev 0 0
gvfsd-fuse /run/user/zhangjianlin/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,user=zhangjianlin 0 0
可以用chattr将檔案設定為不可修改
實戰演練
将一個檔案設定為不可修改
chattr +i file
或者sudo chattr +i file
rm file出錯
移除不可修改的屬性
chattr -i file
修改檔案三個時間
touch -a 更檔案通路時間
touch -m 更改檔案内容修改時間
touch -d 時間戳
列舉檔案夾下的類型統計資訊
file -b filename
ASXII text
腳本如下
<code>if</code> <code>[ $</code><code># -ne 1 ];</code>
<code>then</code>
<code> </code><code>echo</code> <code>$0 basepath;</code>
<code> </code><code>echo</code>
<code>fi</code>
<code>path=$1</code>
<code>declare</code> <code>-A statarray</code>
<code>while</code> <code>read</code> <code>line;</code>
<code>do</code>
<code> </code><code>ftype=`</code><code>file</code> <code>-b </code><code>"$line"</code><code>`</code>
<code> </code><code>let</code> <code>statarray[</code><code>"$ftype"</code><code>]++;</code>
<code> </code><code>done</code><code>< <(</code><code>find</code> <code>$path -</code><code>type</code> <code>f -print)</code>
<code> </code>
<code>echo</code> <code>========</code><code>file</code> <code>types and counts==========</code>
<code>for</code> <code>ftype </code><code>in</code> <code>"${!statarray[@]}"</code><code>;</code>
<code> </code><code>echo</code> <code>$ftype : ${statarray[</code><code>"$ftype"</code><code>]}</code>
<code>done</code>
結果
$ bash filestat.sh .
========file types and counts==========
Bourne-Again shell script, ASCII text executable : 2
empty : 2
原理
while read line
do
echo $line
done<A
<A寫在最後相當于給整個while do 語句加了一個限制條件,讀取檔案A裡每行至檔案尾結束
while read line<A
echo $line
done
<A寫在前面,整個while do語句就沒有限制條件, 因為 read line<A這個始終為真
表示 不停地 讀取A中的第一行,指派給參數line,然後列印參數line的值.
done< <(find $path -type f -print)
<(find $path -type f -print) 等同與檔案名。隻不過他用子程序輸出代替檔案名
${!statarray[@]} 用于傳回一個數組索引清單
第四章。讓文本飛
正規表達式入門
更多内容百度
比對一個ip位址
[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
grep搜尋文本
擴充内容
遞歸搜尋包含詞的檔案
grep "text" . -R -n #開發人員常用的指令
如
$ grep "bin" . -R -n
./第三章:42:binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,noexec,nosuid,nodev 0 0
./第三章:66:#!/bin/bash
./second/mvsuffix.sh:1:#!/bin/bash
./second/mvfilename.sh:1:#a!/bin/bash
./touchlearnfiles.sh:1:#!/bin/bash
./第一章.txt:25:#!/bin/bash
./第一章.txt:36:#!/bin/bash
./第一章.txt:45:#!/bin/bash
./第一章.txt:71:#!/bin/bash
./第一章.txt:74:(cd /bin; ls);
./第一章.txt:97:#!/bin/bash
./第一章.txt:117:#!/bash/bin
./第一章.txt:133:line="root:x:0:0:root:root:/bin/bash"
./第一章.txt:178:#!/bin/bash
./first/password.sh:1:#!/bin/bash
./first/dealpasswd.sh:1:#!/bash/bin
./first/dealpasswd.sh:17:line="root:x:0:0:root:root:/bin/bash"
./first/IFSofdiv.sh:1:#!/bin/bash
./first/array_var.sh:1:#!/bin/bash
./first/cilldshell.sh:1:#!/bin/bash
./first/cilldshell.sh:4:(cd /bin; ls);
./first/delaysleep.sh:1:#!/bin/bash
./first/filetest.sh:1:#!/bin/bash
./第二章.txt:160:#a!/bin/bash
./第二章.txt:196:#!/bin/bash
./third/filestat.sh:1:#!/bin/bash
./third/remove_duplicates.sh:1:#!/bin/bash
在grep 搜尋中包括或排除檔案
隻在目錄中遞歸搜尋所有的.c .cpp檔案:
$ grep "main()" . -r --include *.{c,cpp}
搜尋中排除所有的README檔案
$ grep "main()" . -r --exclude "README"
對檔案中的行、單詞和字元進行疊代
實戰
疊代檔案中的每一行
while read line;
echo $line;
done < file.txt
每一行的單詞
for word in $line
echo $word ;
疊代一個單詞中方的每一個字元
for ((i=0;i<${#word};i++))
echo
${word:i:1};
${word:start_position:no_of_characters} 傳回變量word所包含的字元串中的一個字竄 :重要
cat touchlearnfiles.sh | (while read line; do echo $line; done)
結果:
#!/bin/bash
arrays=("一" "二" "三" "四" "五" "六" "七" "八" "九" "十")
arraynums=(first second third fourth fifth sixth seventh eighth ninth tenth)
read -p "please input the number of caption:" num;
touch "第${arrays[$num-1]}章.txt"
mkdir ${arraynums[$num-1]}
awk列印多列資料,并在列間插入指定的字元
$ ls -l | awk '{ print $1" : " $8 }'
實戰演練:列印不同行或樣式之間的文本
列印從第M行到N行這個範圍内的所有文本,使用下面文法:
$ awk 'NR==M, NR==N' filename
把M跟N換成數字
$ seq 100 | awk 'NR==4, NR==6'
要列印處于'/start_pattern/,/end_pattern/' filename
$ cat section.txt
line with pattern1
line with pattern2
line with pattern3
line end with pattern4
line with pattern5
$awk '/pa.*3/, /end/' section
回文判斷 最簡單的使用指令rev指令
rev 接受一個檔案或stdin作為輸入,并逆序列印每一行内容
試試下面的代碼
<code>#/bin/bah</code>
<code>string=</code><code>"malayalam"</code>
<code>if</code> <code>[[ </code><code>"$string"</code> <code>== </code><code>"$(echo $string | rev )"</code> <code>]]; </code><code>#重點</code>
<code>echo</code> <code>"Palindrome"</code>
<code>else</code>
<code>echo</code> <code>"not palindrome"</code>
解析文本中的點子郵件位址和url
解析email
egrep -o '[A-Za-z0-9.]+@[A-Za-z0-9.]+\.[a-zA-Z]{2,4}'
比對HTTP URL的正規表達式
egrep -o "http://[a-zA-Z0-9.]+\.[a-zA-A]{2,3}"
http://www.google.com
http://code.google.com
[a-zA-Z0-9.]+ “+”表示應該出現多次
用awk實作head、tail和tac
$ awk 'NR <=10' filename
模拟tail指令列印檔案的後10行
$ awk '{ buffer[NR % 10] = $0;} END { for(i=1;i<11;i++){print buffur[i%10] } }' filename
檔案切片與參數操作
替換變量内容中的部分文本
$ var="this is a line of text"
$ echo ${var/line/REPLACED}
"This is a REPLACED of text"
$name ${name%$1}$2 #${name%\.*} "%"号除去字尾名,隻取檔案名
${file_name#*.} 隻留擴充名或字尾
生成子竄
${variable_name:start_positon:length}
最後一個字元索引記為-1,使用負數索引的話,必須将負數放入括号内,例如(-1)就是最後一個字元的索引
如
string={a..z}
echo ${string:(-2):2}
yz
本文轉自lilin9105 51CTO部落格,原文連結:http://blog.51cto.com/7071976/1251296,如需轉載請自行聯系原作者