標題索引
| |
有用的教學網站
curl http://v2.wttr.in/taoyuan curl http://wttr.in/taoyuan
$ numfmt --grouping 123456789 123,456,789 $ numfmt --from=si 2M 2000000 $ numfmt --from=iec 2M 2097152 $ numfmt --from=iec-i 2Gi 2147483648 $ numfmt --to=iec 1000000 977K
去除檔案內的單引號
tr -d \'
TMPFILE=$(mktemp) || exit 1 echo "Our temp file is $TMPFILE"
# specify the directory TMPFILE=$(mktemp -p /path/to/tmpdir) echo "Our temp file is $TMPFILE"
#!/bin/bash # Deleting the File After Script Exit trap 'rm -f "$TMPFILE"' EXIT TMPFILE=$(mktemp)|| exit 1 echo "Our temp file is $TMPFILE"
cat $1 > /tmp/$1.tmp
while(true)
do
if [[ $(diff $1 /tmp/$1.tmp) ]]
then
$2
cat $1 > /tmp/$1.tmp
fi
sleep 2
done
Usage: watchdog.sh log.txt "echo hello"
編輯 /root/.bashrc,加上這一行
echo "ALERT – Root Shell Accessed by `whoami` Login on:" `date` | mail -s "Alert: User `whoami` logged on to `hostname`" user@your.company.com
// 查出目前使用哪種 SHELL
#> ps -p $$ #> echo $0 #> echo $SHELL
// 執行 SHELL 的方式
#> sh file #> . file #> source file
// 在 SHELL 內執行另一個外部 SHELL 或指令
使用 pipe line
echo"md5sum $X > $X.sum "| bash
使用 eval
get_arch="uname -p" if [ "`eval "$get_arch"`" = "i686" ]; then .... fi
// 命令模式提示字元的路徑名稱太長
加上這變數
PROMPT_DIRTRIM=2
usernames=$(cat /etc/passwd | grep bash | sed 's/:.*//g)
for user in $usernames; do
echo "somepassword" | passwd --stdin $user
done
有些版本不支援 --stdin,可以改用
usernames=$(cat /etc/passwd | grep bash | sed 's/:.*//g)
for user in $usernames; do
echo "$user:somepassword" | chpasswd
done
建立隨機密碼
cat /dev/urandom | tr -c -d '[:alnum:]' | head -c 16;echo
command1 | command2 | commandN OR command1 | filter_data_command > output OR get_data_command | verify_data_command | process_data_command | format_data_command > output.data.file
取得每個指令的回應碼
// 輸出每個指令的回應碼,以 Array 方式
echo "${PIPESTATUS[@]}"
// 輸入第一個與第二個指令的回應碼
echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}"
| 鍵盤 | 說明 |
| Ctrl + a | 游標快速移到做前端 |
| Ctrl + e | 游標快速移到最末端 |
| Alt + f | 游標往前移動一段文字 |
| Alt + b | 游標往後移動一段文字 |
| Ctrl + d | 刪除目前游標上的一個字元 |
| Alt + d | 刪除目前游標上的一段文字 |
| Ctrl + n | 下一個歷史指令 |
| Ctrl + p | 上一個歷史指令 |
| Ctrl + u | 裁掉目前游標之前的文字 |
| Ctrl + k | 裁掉目前游標之後的文字 |
格式化輸出
# (printf "DeviceName On MountPoint Type FileSystem\n";mount) | column -t DeviceName On MountPoint Type FileSystem /dev/mapper/vg_homepbx-lv_root on / type ext4 (rw) proc on /proc type proc (rw) sysfs on /sys type sysfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) tmpfs on /dev/shm type tmpfs (rw) /dev/sda1 on /boot type ext4 (rw) none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
快速建立一個目錄且設定好 owner/group,存取權限。
/usr/bin/install -o www-data -g www-data -m 0755 -d /var/log/freegeoip
CPU:
cat /proc/cpuinfo
Memory:
cat /proc/meminfo
OS Version:
cat /proc/version
#!/bin/bash
str_list=("aaa" "bbb" "ccc" "ddd")
echo ${#str_list[@]}
for i in ${str_list[@]}
do
echo "$i"
done
# Script to split a string based on the delimiter
my_string="Ubuntu;Linux Mint;Debian;Arch;Fedora"
IFS=';' read -ra my_array <<< "$my_string"
#Print the split string
for i in "${my_array[@]}"
do
echo $i
done
# Script to split a string based on the delimiter
my_string="Ubuntu;Linux Mint;Debian;Arch;Fedora"
my_array=($(echo $my_string | tr ";" "\n"))
#Print the split string
for i in "${my_array[@]}"
do
echo $i
done
指定 sender name)
使用 Mutt,適用 CentOS 4
$ export EMAIL="No Reply<noreply@my.com>" $ echo "mail body" | mutt -s "Test Mail" touser@my.com
使用 mailx,適用 AIX 5.3
$ echo "mail body" | mailx -s "Test mail" -r noreply@my.com touser@my.com
從外部的 SMTP server 轉信)
使用 mailx 指令
// 安裝 mailx yum install mailx // 寄信 $ echo "This is the message body and contains the message" | mailx -v \ > -r "someone@example.com" \ > -s "This is the subject" \ > -S smtp="mail.example.com:587" \ > -S smtp-use-starttls \ > -S smtp-auth=login \ > -S smtp-auth-user="someone@example.com" \ > -S smtp-auth-password="abc123" \ > -S ssl-verify=ignore \ > yourfriend@gmail.com
TIPs:
-v 會顯示完整連線訊息,內容類似如下
Resolving host smtp.gmail.com . . . done.
Connecting to 74.125.68.109:587 . . . connected.
220 mx.google.com ESMTP je4sm32812877pbd.94 - gsmtp
>>> EHLO enlightened
250-mx.google.com at your service, [122.163.43.21]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
// for loop 的應用
$> for i in var1 var2 var3; do echo $i; done
$> for ((i=1;i<=10;i++)); do echo $i; done
$> for i in $(ls *.log); do echo $i; done
$> for t in {1..10};do echo $t; done
1
2
3
4
5
6
7
8
9
10
$> for t in {1..10..2};do echo $t; done
1
3
5
7
9
## 列出目前資料夾的所有目錄名稱
$> for dir in */;do echo "${dir%/}"; done
## 讀取檔案內容
$> cat tables_name.lst | while read sch tab;do
> echo "export to $tab.ixf of ixf messages export_$tab.msg select * from $sch.$tab"
> done
// while loop 的應用
// 每 3 秒監看 /worktmp 的磁碟使用狀況
$> while true;do
> df -h | grep /worktmp
> sleep 3
> done
// 管理 DB2 時常用
$> while read s t;do
> db2 "select count(*) from $s.$t"
> done < tables.lst > count-tables.out
如果是 CSV
$> while IFS=, read s t;do
> db2 "select count(*) from $s.$t"
> done < tables.csv > count-tables.out
// 大量刪除名稱包含有 /plugins/mactrack 的程式
$> ps -ef | grep "/plugins/mactrack" | awk '{system("kill " $2);}'
// 建立臨時檔案或目錄
TMPFILE=$(mktmp)
TMPDIR=$(mktmp -d)
這分別會在 /tmp 目錄建立以亂數取名的臨時檔案或臨時目錄,記得程式最後要將這些臨時檔案目錄移除
// 迴圈計數 Loop Counter
x=1
while [ $x -le 5 ]
do
echo "Welcome $x times"
x=$(( $x + 1 )) 或者 x=$[$x + 1]
done
sort -t ',' -k5,5 -k1,1 -k9,9 -k3,3 -k11,11 my.csv
SHELL 寫法
NOW=`date "+%Y/%m/%d %H:%M:%S"` eval `date "+day=%d; month=%m; year=%Y"` BKNAME="cacti-backup-$year-$month-$day.tar.gz"
NOWD=$(date +"F") # YYYY-MM-DD NOWT=$(date +"%T") # H:M:S
%T time; same as %H:%M:%S
將 Date 轉換為 EPOCH 時間格式
用 perl 可用於 AIX
perl -e 'use Time::Local; print timelocal(0,25,1,11,11,2008), "\n";'
常用幾種格式
# echo `date "+%y-%m-%d_%H%M%S"` 17-05-22_105503 # echo `date "+%Y/%m/%d"` 2015/07/17 # echo `date "+%F"` 2015-07-17 # date --date="49 days ago" 日 9月 11 16:17:02 CST 2016 # date --date="1 month ago" 五 9月 30 16:17:34 CST 2016
計算程式執行所花費的時間
start=`date "+%Y/%m/%d %H:%M:%S"` start_s=$(date -d "$start" +%s) Sleep 20 end=`date "+%Y/%m/%d %H:%M:%S"` end_s=$(date -d "$end" +%s) diff=$((end_s - start_s))
// 找出大於 1000 MB 的檔案
find / -type f -size +1000M
// 搬移指定日期範圍的檔案
將修改日期是 2012 - 2014 的所有檔案搬移至 /export_data/2012-2014。
touch --date "2012-01-01" /tmp/start
touch --date "2015-01-01" /tmp/end
find /home/ams/ipdr -type f -newer /tmp/start -not -newer /tmp/end > 2012-2014.lst
find /home/ams/ipdr -type f -newer /tmp/start -not -newer /tmp/end -exec cp -a {} /export_data/2012-2014 \;
find /home/ams/ipdr -type f -newer /tmp/start -not -newer /tmp/end -exec rm -f {} \;
// 列出 2018-03-20 至 2018-04-10 期間曾修改過的檔案
find ~/ -xdev -newermt 2018-03-20 \! -newermt 2018-04-10 -type f -ls
// 列出 365天以前/20分鐘以前 的所有檔案
find ./ -ctime +365 -ls find ./ -cmin +20 -ls
TIP:
ctime 檔案建立時間
mtime 最近檔案修改時間
atime 最近存取檔案時間
// 找尋3日內曾異動過的檔案,並轉換 Excel format(csv)
find . -xdev -mtime -3 -ls > found.list
sed 's/^[ ]*//g;s/[ ][ ]*/ /g' found.list | awk '{print $3","$5","$6","$7","$8" "$9","$10","$11}' > found.list.csv
// 列出剛剛異動過的檔案
最近 5 分鐘異動過的檔案(包含權限與新增檔案) find dir -cmin -5 最近 10 分鐘修改過的檔案 find dir -mmin 10
// 目錄 data 內有許多以日期命名的小 log,需要將去年的所有 log 搬到新目錄 archive-2013
註:排除目錄 ./archive-2013
cd data/
mkdir archive-2013
find ./ -path "./archive-2013" -prune -o -name "dcdb_13*" -exec mv {} archive-2013 \;
TIPs:
要排除多個目錄時可以改成
find ./ \( -path "./dir1" -o -path "./dir2" \) -prune -o -name "dcdb_13*" -exec mv {} archive-XXXX \;
// 列出最大檔案的清單
find . -type f -exec wc -c {} \; | sort -nr | head
// 檔案搜尋結果按時間先後作排序
find /istrpt/arlog/ -name "*.LOG" -print | xargs ls -lt
用 find
計算目前目錄底下所有檔案數
find . -type f | wc -l
計算第一層所有子目錄的檔案數並排序清單
find . -maxdepth 1 -type d -print0 | xargs -0 -I {} sh -c 'echo $(find {} -type f | wc -l) {}' | sort -n
NOTE: 第一層子目錄名稱不可包含空格
用 rsync 方式計算 /usr 底下檔案數
rsync --stats --dry-run -ax /usr /tmp Number of files: 326,373 (reg: 211,698, dir: 24,284, link: 90,391) Number of created files: 326,373 (reg: 211,698, dir: 24,284, link: 90,391) Number of deleted files: 0 Number of regular files transferred: 211,698 Total file size: 7,180,685,730 bytes Total transferred file size: 7,178,524,818 bytes NOTE: 這指令實際不會作檔案複製,/tmp 只是一個假目錄,回傳結果是 reg: 211698 就是檔案總數
用 tree
tree /mydir -a | tail -n 1 5 directories, 56 files NOTE: 當目錄底下有包含 symbolic link 也會被計算
mkdir {AAA,BBB,CCC}
更多教學:http://www.cyberciti.biz/faq/grep-re...r-expressions/
// 字串過濾搜尋
使用 . (period) 表示一個任意字元 $ grep dev.sda /etc/fstab /dev/sda3 / reiserfs noatime,ro 1 1 /dev/sda1 /boot reiserfs noauto,noatime,notail 1 2 /dev/sda2 swap swap sw 0 0 #/dev/sda4 /mnt/extra reiserfs noatime,rw 1 1 使用 [ ] $ grep dev.sda[12] /etc/fstab /dev/sda1 /boot reiserfs noauto,noatime,notail 1 2 /dev/sda2 swap swap sw 0 0 使用 [^12] 表示非1,2字元 $ grep dev.sda[^12] /etc/fstab /dev/sda3 / reiserfs noatime,ro 1 1 #/dev/sda4 /mnt/extra reiserfs noatime,rw 1 1 使用正規表示 $ grep '^#' /etc/fstab # /etc/fstab: static file system information. # $ grep '^#.*\.$' /etc/fstab # /etc/fstab: static file system information. # $ grep 'foo$' filename 搜尋與關鍵字大小寫一致的行 grep -w "boo" myfile.txt 搜尋包含特殊字元 *** 的關鍵字 grep '\*\*\*' myfile.txt 更多應用語法 grep '[vV][iI][Vv][Ee][kK]' filename grep '[vV]ivek' filename grep -w '[vV]ivek[0-9]' filename grep 'foo[0-9][0-9]' filename grep '[A-Za-z]' filename grep [wn] filename
// 搜尋多個關鍵字(使用正規運算式)
> ls /var/log/ | grep -E "http|secure" 或 > ls /var/log/ | grep "http\|secure"
// 檢查設定檔的參數
// 在許多檔案內尋找特定字串內容
應用:程式碼編寫及除錯
cd /var/www/html
grep -r "[搜尋關鍵字]" *
grep -Ril "specific_text" /path/to/dir
// 搜尋特定字串的文字段落內容
應用:檢查系統的硬體裝置,以及類似 AIX 的 grep -p
# lspci -v | awk '/ATI/,/^$/'
01:03.0 VGA compatible controller: ATI Technologies Inc Rage XL (rev 27) (prog-if 00 [VGA])
Subsystem: Compaq Computer Corporation: Unknown device 001e
Flags: bus master, stepping, medium devsel, latency 64
Memory at fc000000 (32-bit, non-prefetchable) [size=16M]
I/O ports at 3000 [size=256]
Memory at fbff0000 (32-bit, non-prefetchable) [size=4K]
Capabilities: [5c] Power Management version 2
檔案:grepp.awk
使用方法:
#> lspci -v | grepp.awk ATI
Sample#1:
find . -not -type d -printf "%T+ %p\n" | sort -r | awk '{print $2}' | head -n 5
./b01.tar.gz
./b02.tar.gz
./b03.tar.gz
./b04.tar.gz
./b05.tar.gz
Sample#2:
find . -name "*" -type f | xargs ls -lt | head -n 5 | awk '{print $9}'
./b11.tar.gz
./b10.tar.gz
./b09.tar.gz
./b08.tar.gz
./b07.tar.gz
# 從小到大 ls -l -Sr1 /path-to-dir # 從大到小 ls --sort=size /path-to-dir # 排序後清單,逐一做壓縮 ls -Sr1 worktmp/ | while IFS=$'\n' read -r file; do gzip -v9 "$file"; done # 列出前十大的檔案清單 du -csk * | sort -rn | head -10
#轉換成小寫
toLower() {
echo $1 | tr "[:upper:]" "[:lower:]"
}
#轉換成大寫
ToUpper() {
echo $1 | tr "[:lower:]" "[:upper:]"
}
# Checking if DB XXX existed # if existed, return 0 mysql -uroot -p$DBPASS --batch --skip-column-names -e "SHOW DATABASES LIKE '$DBNAME';" | grep $DBNAME > /dev/null; echo $?
(1) 字串或文字的比對
Str1 == str2 | 當str1與str2相同時, 傳回True Str1 != str2| 當str1與str2不同時, 傳回True Str1 < Str2 Str1 <= Str2 Str1 > Str2 Str1 >= Str2 Str | 當str不是空字符時, 傳回True -n str | 當str的長度大於0時, 傳回True -z str | 當str的長度是0時, 傳回True
(2) 數字(整數) 比對
Int1 -eq int2 |當int1等於int2時, 傳回True Int1 -ge int2 |當int1大於/等於int2時, 傳回True Int1 -le int2 |當int1小於/等於int2時, 傳回True Int1 -gt int2 |當int1大於int2時, 傳回True Int1 -ne int2 |當int1不等於int2時, 傳回True Int1 -lt int2 |當int1小於 int2時, 傳回True
More Sample Codes:
(3) 檔案的比對
-e file | 檔案是否存在 -d file | 當file是一個目錄時, 傳回 True -f file | 當file是一個普通檔案時, 傳回 True -r file | 當file是一個可讀檔案時, 傳回 True -s file | 當file檔案長度大於0時, 傳回 True -w file | 當file是一個可寫檔案時, 傳回 True -x file | 當file是一個可執行檔案時, 傳回 True
(4) shell的邏輯操作符用於修飾/連接包含整數,字符串,文件操作符的表達式
! expr |當expr的值是False時, 傳回True
更多範例
| 變數 | 說明 |
| $0 | 腳本檔名 |
| $1 | 第1個參數 |
| $2 | 第2個參數 |
| ${10} | 第10個參數 #10 |
| $# | 參數的個數 |
| $* | 顯示所有參數 (作為一個字串) |
| $@ | 顯示所有參數 (每個為一個獨立字串) |
| ${$*} | 傳遞到腳本中的參數的個數 |
| ${$@} | 傳遞到腳本中的參數的個數 |
| $? | 腳本結束後的傳回值 |
| $$ | 腳本的程序 ID |
| $_ | 前個命令的最後一個參數 |
| $! | 最後一個執行程序的 ID |
| u=${1:-root} | 如果 $1 未指定,就賦予值 root |
| u=${USER:foo} | 如果 $USER 未指定,就賦予值 foo;無法用於 $1, $2 變數 |
| len=${#var} | 計算 $var 字串的長度 |
如果 $2 未指定或空值,輸出錯誤訊息
${varName?Error varName is not defined}
${varName:?Error varName is not defined or is empty}
MESSAGE="Usage: mkjail.sh domain-name" ## define error message
_domain=${2:?"Error: ${MESSAGE}"} ## you can use $MESSAGE too
${varable} 進階用法
https://linuxconfig.org/introduction...ter-expansions
#!/bin/sh LOG="my.log" ( .... ) 2>&1 | tee -a $LOG
TIPs
不適用在內容裡有 python 指令的訊息輸入,輸入等待的畫面會無法顯示。
printf "%-40s ..................%s\n" "Disable the service $1" "[$2]"
Disable the service apmd ..................[OK] Disable the service bluetooth ..................[OK] Disable the service hidd ..................[OK] Disable the service cups ..................[OK] Disable the service firstboot ..................[OK] Disable the service readahead_early ..................[OK]
printf "%40s ..................%s\n" "Disable the service $1" "[$2]"
Disable the service apmd ..................[OK]
Disable the service bluetooth ..................[OK]
Disable the service hidd ..................[OK]
Disable the service cups ..................[OK]
Disable the service firstboot ..................[OK]
Disable the service readahead_early ..................[OK]
日期運算
YEAR=$((YEAR-1)) MONTH=$((MONTH-1)) echo "($YEAR + ($YEAR/4) - ($YEAR/100))"
X的Y次方
pow() {
if [ -z "$1" ]; then
echo "usage: pow <base> <exponent>"
else
echo "$1^$2" | bc
fi
}
pow2() {
if [ -z "$1" ]; then
echo "usage: pow <base> <exponent>"
else
echo "$[$1**$2]"
fi
}
pow 2 3
# $1 is month, $2 is day, $3 is year
# Strip off leading off zeros from month and day
MONTH=${1#0}
DAY=${2#0}
YEAR=$3
NAME=${1%.*}
echo $NAME
更多範例
Operator "#" means "delete from the left, to the first case of what follows."
$ x="This is my test string."
$ echo ${x#* }
is my test string.
Operator "##" means "delete from the left, to the last case of what follows."
$ x="This is my test string."
$ echo ${x##* }
string.
Operator "%" means "delete from the right, to the first case of what follows."
$ x="This is my test string."
$ echo ${x% *}
This is my test
Operator "%%" means "delete from the right, to the last case of what follows."
$ x="This is my test string."
$ echo ${x%% *}
This
cmp -s file1 file2 rc=$?
#!/bin/bash FILENAME=/home/heiko/dummy/packages.txt FILESIZE=$(stat -c%s "$FILENAME") echo "Size of $FILENAME = $FILESIZE bytes."
// 指定的檔案 readlink -f <file.name> // 目前檔案 MY_PATH=$(readlink -f "$0") ;目前檔案的絕對路經 MY_PATH=$( cd $( dirname "$0" ) && pwd )
>echo $0 ./test.sh >echo `basename $0` test.sh
; 過濾郵件位址的使用者名稱 ; 列出所有 fax 開頭網域的郵件位址的使用者名稱 expr "001123@fax.home.net" : '\(.*\)@fax*'
註:
\( \) 等於是 ( ),所包含的就是要輸出內容
. 任何字元
.* 不限字數的任何字元
[^=] 非 = 的字元
搜尋字串
awk '/^this/{print $0}' ;與 sed -n '/^this/p' 相同
我們經常使用 sort 與 uniq 指令,從檔案中找出並移除重複項目。不過如果你不希望你的原始檔被排序或更動,這時正是 awk 派上用場的時候,我們可以用 awk 截取不重複記錄並儲存在新的檔案中:
awk '!x[$0]++' filewithdupes > newfile
搜尋含 disabled 的行,並列出第 1, 3 欄的內容
awk '/disabled/{print $1, $3}'
取值做計算
awk '{print "up " $1 /60 " minutes"}' /proc/uptime
df -lP -text4 |awk '{sum += $4} END {printf "%d GiB\n", sum/1048576}'
df -lP -text4 |awk '{sum += $4} END {printf "%d GiB\n", sum/2**20}'
加上判斷式
$> df -k |grep "/dev/" | awk '($2 > 0 && ((1 - $3/$2) > 0.9) ) {print $0 }'
$> awk -F" " '{print ($7 != "A")?$0"***":$0}' myfile
搜尋每行的第9欄,如果不是 0x00000000 時就顯示該行訊息
$> cat info.out | awk '($9 != "0x00000000") {print}'
列出 uid >= 500 且 <= 10000 的行
$> export UGIDLIMIT=500 $> awk -v LIMIT=$UGIDLIMIT -F: '($3>=LIMIT) && ($3<=10000)' /etc/passwd
解決長整數顯示問題
$ awk 'BEGIN {print 12345678901234567890}'
1.23457e+19
方法一
$ awk 'BEGIN {printf("%d\n", 12345678901234567890)}'
12345678901234567168
方法二
$ awk 'BEGIN {OFMT="%.0f"; print 12345678901234567890}'
12345678901234567168
列出 uid=0 的帳號
$> awk -F: '($3 == "0") {print}' /etc/passwd
列出最後一個欄位的值
ls -ltd */ | awk -F ' ' '{print $NF}'
格式化輸出
awk '{ printf("1-minute: %s\n5-minute: %s\n15-minute: \
%s\n",$1,$2,$3); }' /proc/loadavg
計算目錄的檔案大小
; 列出第 100 行以下的所有文字 ; 若要刪除,可將 p 換成 d。 sed -n '100,$p' my.txt ; 列出第 3 行以上的所有文字 sed '3q' my.txt ; 列出關鍵字 all 以下所有行 sed -n '/all/,$p' my.txt ; 搜尋關鍵字,並列出這個段落的所有文字 sed -n '/keyword/,/^$/p' ; 列出關鍵字 Top 與 Bottom 之間的所有文字 sed -n '/Top/,/Bottom/p' ; 搜尋字串的那一行 sed -n "/PATTERN/p" my.txt ; 在第 2 行的上方,插入文字 xxx sed '2i xxx' my.txt ; 在搜尋的行下方新增字串 sed -e '/patterm/ a\newstring' my.txt ; 在所有文字的行首加上 # sed 's/^/# /' my.txt ; 在所有文字的行尾加上 End sed 's/$/ End/' my.txt ;刪除行首為# 的行 sed '/^#/d' ; 刪除行首為 # 或空白的行 sed '/^#\|^$/d' ;刪除多個關鍵字的行, ADMIN_ERP_ROLE, RPT01,... sed '/ADMIN_ERP_ROLE/d;/RPT01/d' ;刪除空白行 sed '/^$/d' sed '/^\s*$/d' ;移除行裡的空白與 Tab 字元 sed 's/^[ \t]*//' sed 's/^[ \t]*//;s/[ \t]*$//' ;將每一行裡是兩個以上空白字元, 都換成一個 comma 符號 sed "s/ \+/,/g" ; 刪除空格 sed 's/[[:space:]]//g' mywords ; 刪除所有行尾的空格字元 sed -i 's/[[:space:]]*$//' ; 刪除行尾的 ^M (CR 字元) sed 's/^M//g' NOTE: to get ^M type CTRL+V followed by CTRL+M sed 's/\r$//g' ; 刪除 iXXXX 的帳號, XXXX 是數字 sed '/^i[0-9]*/d' mypasswd ;執行多個規則 sed -e '/^#/d' -e '/^$/d' ;快速取代字串 sed 's/old/new/' mywords sed 's|old|new|' mywords ; 搜尋關鍵字 'astlogdir =>' 的這一行,取代行字串為 'astlogdir => /mnt/usb/asterisk_log' ; .*$ 表示行尾前的所有字串 sed -i 's/astlogdir =>.*$/astlogdir => \/mnt\/usb\/asterisk_log/g' ; 搜尋 'none',並且在該行行首加上 '#' sed 's/none/#&/g' mywords ; 在字串 'daemon' 的下方插入另一個檔案 3.txt 的內容 sed '/daemon/r 3.txt' mywords ; 搜尋文字 'daemon',將符合的內容寫到檔案 3.txt sed -n '/daemon/w 3.txt' 1.txt ; 將符合文字 'root' 內容的下一行,插入特定的文字 'test test' [root@linux-3 ~]# sed ‘/root/a test test’ 1.txt root:x:0:0:root:/root:/bin/bash test test bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin ; 將符合文字 'daemon' 內容的上一行,插入特定的文字 'test test' [root@linux-3 ~]# sed '/^daemon/i test test' 1.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin test test daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin ; 搜尋所有文字是 'ext3' 的,用 [ ] 框起來 sed 's/ext3\+/[&]/g' my.txt ; 搜尋文字並取代部份的內容 sed -i 's/^\(User\|Group\).*/\1 asterisk/' /etc/httpd/conf/httpd.conf
// 找出關鍵字的右側字串內容
$ cat cookie.txt xxxx FALSE / FALSE 0 PHPSESSID dbbr5nsmib9tgm0h97sbq8ovd0 $ cat cookie.txt | sed 's/^.*PHPSESSID[ \t]*//' dbbr5nsmib9tgm0h97sbq8ovd0
// 找出行的左側內容
列出 10.14.25.196 與 GA016E38 (Hex IP)
$ cat input.txt GA160223.MAE3.219594040120 10.14.25.196.49611.200203080358 GA016E38.O5FA.259D81215343 10.4.1.29.41266.200114031620 GA12640A.M6EE.20EDC3093010 $ sed 's/^\(.*\)\.[A-Z0-9]*\.[A-Z0-9]*/\1/' input.txt GA160223 10.14.25.196 GA016E38 10.4.1.29 GA12640A
// 對 CSV 檔案的內容,將所有分隔符號 comma 置換成 @@,但必須排除有包含 comma 的文字敘述,這些文字內的 comma 前個字元會有個空白
sed 's/\(,\)\([^ ]\)/@@\2/g' orig.csv
TIPs:
s 搜尋
\( \) \( \) 用括弧區分兩個字元
[^ ] 非空白的字元
\2 第二個字元,這裡要配合括弧的用法
g 作全文置換,若沒有此參數,預設只會置換第一個符合的字元
// 搜尋 A.AA B.BB C.CC 3個數值,並以指定的格式輸出
TIPs:
^\([0-9]\+\.[0-9]\+\) \([0-9]\+\.[0-9]\+\) \([0-9]\+\.[0-9]\+\).*$ 搜尋語法
1-minute: \1\n5-minute: \2\n15-minute: \3 輸出語法
// 取代所有的 mailbox = xxx 為 mailbox = xxx@context
sed 's/^mailbox = [0-9]*/&@context/g' users.conf
// 搜尋特定區段的 AllowOverride None
只取代這個區段所包含的關鍵字
<Directory "/var/www/html">
...<Directory>
sed -i ':a;N;$!ba;s/AllowOverride None/AllowOverride All/2' /etc/httpd/conf/httpd.conf
// 擷取 { } 所包含的所有文字
<br/> <b>Notice</b>: Undefined variable: sn in <b>/var/www/raida/service/fix.php</b> on line <b>259</b><br/> {"server":"RAIDA17","sn":"","status":"success","message":"Fixed: Unit's AN was changed to the PAN. Update your AN to the new PAN.","time":"2017-04-08 06:08:25"}
echo $( cat http_get.txt ) | sed 's/.* \({.*}\)$/\1/'
// 擷取 [ ] 內的文字
echo "[1070059:1,1070060:1,1070039:1]" | sed 's/^\[\(.*\)\]$/\1/'
lsof -p `pidof <app_name>`
grep -Ev "^(#|;)" example.txt
延伸應用:
自動刪除文字檔內所記載的目錄及檔案,例如:
# file: remove.list # please remove this directory and files below /path/to/file.1 /path/to/file.2 /path/to/dir/ /path/to/dir-1/
依照檔案清單做連續刪除的指令行:
grep -Ev "^(#|;)" remove.list | xargs -n 1 ls -l grep -Ev "^(#|;)" remove.list | xargs -n 1 rm -rf
## *.old -> *.new for fname in $(ls *.old);do echo "mv $fname ->"; echo $(echo $fname |sed 's/.old/.new/');mv $fname $(echo $fname | sed 's/.old/.new/');done
for SHELL process:
#!/bin/bash # /path/to/my/shell.sh & echo $PPID
# pidof <app_name>
#!/bin/bash echo $$
for java process:
#!/bin/bash # /path/to/java myjava.jar & echo $!
internip=`ifconfig | grep -m 2 ^ | cut -f 2 -d ":" | cut -f 1 -d " " | tail -1`
privnet="${internip%.*}.0/255.255.255.0"
echo $internip
echo $privnet
#!/bin/bash
devs=`ip -o link | cut -f 2 --delimiter=' ' -`
echo "devs="$devs
for i in $devs; do
dev_name=$(echo ${i%:})
ip=$(ifconfig $d) && ip=${ip#*inet addr:} && ip=${ip%% *}
echo "Device Name: "$dev_name
echo "Device IP: "$ip
echo "-------------"
done