Bash


Tricks

mv main.c main.cpp
mv main{.c,.cpp}
mv main{,.bak}

!!:s/old/new
^old^new

# There are two ways for redirecting standard output and standard error
# &>word and >&word
# The first one is preferred. It is semantically equivalent to
# >word 2>&1

# 使用 inode 来操作文件,从 Windows 上传中文文件名的文件到 Linux 时,有可能会出现文件名乱码。
# 这种情况下,我们可以通过 inode 来重命名文件。
cd /path/to/file/
# get the inode number of the specified file
ls -i
# use find to rename it
find . -inum inode -print -exec mv {} newfilename \;

find

find . -type f -name "*.tmp" -delete
find . -type d -name .svn | xargs rm -f
find . -type d -name .svn -exec rm -rf {} \;

iconv

# iconv -l
iconv -f CP936 -t UTF-8 readme.txt

sed

# get the error code ([112210]) from the error log file
# one error code per line (112210)
grep -oE '\[[0-9]{6}\]' error.log | sed -e 's/\[\(.*\)\]/\1/' > error_code.txt
# summary
for i in $(sort error_code.txt | uniq)
do
  awk '/'$i'/{s+=1}END{printf("%d, %d/%d, %.2f%%\n", '$i', s, NR, s*100/NR)}'
done

# dos2unix & unix2dos
sed -i -e 's/\r//' file
sed -i -e 's/$/\r/' file

# sed 转义
# 单引号内,转义符`\`才会生效。
# 使用其它分隔符,例如`:`,`#`,特殊符号按字面值处理。
# openssl passwd -1 -salt 'password' 'default'
sed -i -e '/^default_pass/s/\$1\$mF86\/UHC\$WvcIcX2t6crBz2onWxyac./\$1\$password\$tG3GcpvNzjFuIcmm.w5I30/'
sed -i -e ':^default_pass:s:$1$mF86/UHC$WvcIcX2t6crBz2onWxyac.:$1$password$tG3GcpvNzjFuIcmm.w5I30:'

awk

ls -l --time-style=+%Y%m%d%H%M%S | awk '/JPG/ {print $6,$7}' | sed -e 's/\([0-9]\{12\}\)\(.*\)/touch -t \1\.\2/'

xargs

# -l1 把一行作为一个参数。
# -i{} 用{}来替代参数,{}可省略。
ls -al | xargs -l1 -i{} echo {} >> out.txt

Bash

逻辑表达式(())
条件表达式[[]]

if

#!/bin/bash
if [[ "foo" = "foo" ]]; then
  echo expression evaluated as true
else
  echo expression evaluated as false
fi

while

#!/bin/bash
COUNTER=0
while [[ $COUNTER -lt 10 ]]; do     #while; do or while true; do
  echo The counter is $COUNTER
  let COUNTER=COUNTER+1
done

until

#!/bin/bash
COUNTER=20
until [[ $COUNTER -lt 10 ]]; do
  echo COUNTER $COUNTER
  let COUNTER-=1
done

for

#!/bin/bash
# for i in a b c;
# for i in $(ls);
# for i in {0..9};
# for i in `seq 1 10`;
for ((i=0;i<10;i++));
do
  echo $i
done

example

for i in {20101001..20101031}
do
  echo ${i:4:4}; # ${i:start:count}
done

for ((i=0;;i++))
do
  echo $i;
  date +%T.%N
  c=$(netstat -ntep | grep 192.168.111.113 | wc -l)
  if [ $c = "1" ]; then
    echo $c
  else
    break
  fi
done