Mã nguồn các bài thực hành lập trình shell

Một số qui ước:

Bài thực hành 1.1

Sử dụng cơ chế pipe và định hướng lại vào/ra để stdin một chương trình B có thể nhận được dữ liệu từ stderr của chương trình A

# Lệnh sau đây in ra hai dòng thông báo,
# trong đó có một dòng là thông tin của /etc/passwd
# và dòng kia là thông báo lỗi
ls -l /etc/passwd /tmp/non-existence-file
echo
# Định hướng lại vào ra để wc nhận dữ liệu vào là
# thông báo lỗi
ls -l /etc/passwd /tmp/non-existence-file 2>&1 >/dev/null | wc -l
## ls: cannot access '/tmp/non-existence-file': No such file or directory
## -rw-r--r-- 1 root root 3967 Aug  9 02:33 /etc/passwd
## 
## 1

Bài thực hành 1.2

Sử dụng cơ chế pipe và định hướng lại vào/ra để stdin của một chương trình B có thể đồng thời nhận được dữ liệu từ stdoutstderr của chương trình A

ls -l /etc/passwd /tmp/non-existence-file 2>&1 | wc -l
## 2

Bài thực hành 1.3

Hãy liệt kê danh sách không trùng lặp các chương trình thông dịch lệnh của toàn bộ người sử dụng trong hệ thống, đồng thời in ra tổng số các chương trình thông dịch lệnh khác nhau đó. Chú ý:

cut -d : -f 7 /etc/passwd | sort | uniq -c | sort -n
##       1 /bin/nologin
##       1 /bin/sync
##       1 /sbin/halt
##       1 /sbin/shutdown
##       3 /bin/bash
##      62 /sbin/nologin

Bài thực hành 1.4

Hãy viết một chương trình nhận tham số vào là một thư mục, kết quả ra thông báo thư mục đó có thay đổi về nội dung các tệp bên trong đó hay không.

dir=$HOME/data/spatial
# Tạo file mới .abc
echo "ABC" > $dir/.abc
# Tạo nội dung các tên file, thư mục con thư mục $dir
find $dir 2> /dev/null > /tmp/.dircontent
# Xóa file .abc
rm -f $dir/.abc
# Tạo một file mới trong $dir
echo "A new file" > $dir/.anewfile
find $dir 2> /dev/null > /tmp/.dircontent_new
# So sánh cách 1: Có thay đổi do hai chữ
# ký md5 khác nhau
md5sum /tmp/.dircontent
md5sum /tmp/.dircontent_new
# So sánh cách 2: Chỉ ra cụ thể các thay đổi
diff /tmp/.dircontent /tmp/.dircontent_new -u
# Xóa các file thử nghiệm
rm -f /tmp/.dircontent /tmp/.dircontentnew $dir/.anewfile
## ff5d0767fb6af4fa044bdf602d1ae129  /tmp/.dircontent
## 6abc3bc5f138115447fd3e959b235ea4  /tmp/.dircontent_new
## --- /tmp/.dircontent 2016-11-05 12:18:16.489008670 +0700
## +++ /tmp/.dircontent_new 2016-11-05 12:18:16.494008670 +0700
## @@ -1,7 +1,7 @@
##  /home/chau/data/spatial
## -/home/chau/data/spatial/.abc
##  /home/chau/data/spatial/cumbriaLandUse.tif
##  /home/chau/data/spatial/spbdry.dbf
## +/home/chau/data/spatial/.anewfile
##  /home/chau/data/spatial/birds.dbf
##  /home/chau/data/spatial/badgers.dbf
##  /home/chau/data/spatial/spbdry.shx

Bài thực hành 1.5

Hãy kiểm tra một chương trình với tên cho trước sinh ra bao nhiêu tiến trình đang tồn tại trong hệ thống

process=systemd
# Liệt kê các tiến trình cùng tên, chọn tiến trình có PID bé nhất
ps -ef | grep $process | sort -n -k 2 | head -1 | {
    IFS=' ' read -r name pid ppid rest
    parent=$pid
    ps -ef | {
    nbchild=0
    while IFS=' ' read -r name pid ppid rest; do
                if (( $ppid == $parent )) ; then
                        nbchild=$(($nbchild+1))
                fi
        done
        echo Number of child processes of \'$process\': $nbchild
    }
}
## Number of child processes of 'systemd': 47

Bài thực hành 2.1

Hãy viết một script tự nhân bản: Sau mỗi lần thực hiện, script copy chính nó ra một file có tên là backup.sh

# Nội dung script
cat copy.sh
./copy.sh
echo Nội dung backup:
cat backup.sh
## cp "$0" backup.sh
## echo do something..
## do something..
## Nội dung backup:
## cp "$0" backup.sh
## echo do something..

Bài thực hành 2.2

Viết một script in chính nó ra màn hình với thứ tự các dòng ngược lại

cat while.sh
echo "Reverse file:"
nl while.sh | sort -n -r | cut -f 2-
## while [ $# -gt 0 ]
## do
##  echo $1
##  shift
## done
## Reverse file:
## done
##  shift
##  echo $1
## do
## while [ $# -gt 0 ]

Bài thực hành 2.3

Viết một script xác định các tham số dòng lệnh có là số nguyên hay không

a=123
b=12.3
c=a12
d=1a12
e=sdfsdf
echo -n "$a is " ; let "$a" 2> /dev/null && echo integer || echo not integer
echo -n "$b is " ; let "$b" 2> /dev/null && echo integer || echo not integer
echo -n "$c is " ; let "$c" 2> /dev/null && echo integer || echo not integer
echo -n "$d is " ; let "$d" 2> /dev/null && echo integer || echo not integer
echo -n "$e is " ; let "$e" 2> /dev/null && echo integer || echo not integer
## 123 is integer
## 12.3 is not integer
## a12 is not integer
## 1a12 is not integer
## sdfsdf is not integer

Bài thực hành 3.1

Cho danh bạ điện thoại tel.csv là một file text có nhiều dòng, mỗi dòng có các trường thông tin cách nhau bởi dấu ,. Hãy tính số lượng các số điện thoại MobiFone, VinaPhone, VietTel, … trong file đó.

# Nội dung 3 dòng đầu của file
head -3 tel.csv
## 1,08485876443,"KIM Van Chien",,"a"
## 2,0912025544,"Đỗ Thị Phi Nga","Giảng viên chính Thạc sỹ","Khoa Sư phạm Tiếng Anh/Faculty of English"
## 3,0983669908,"Bùi Minh Đức","Thạc Sỹ","Khoa Công nghệ Thông tin"

Nội dung script:

tel=`cut -d , -f 2 ~/Dropbox/courses/bash/tel.csv`

tksb=`echo "$tel" | while read line
do
    echo ${line:0:3}
done | sort | uniq -c`

echo "$tksb" | {
mf=0
vn=0
while read line
do
    std=`echo $line` # Xoa dau trang o dau dong
    n=${std%% *} # Lay so o field 1
    telco=${std##* } # Lay so o field 2
    case $telco in
    090|093) let "mf=$mf+$n" ;;
    091|094) let "vn=$vn+$n" ;;
    # ....
    esac
done
echo "Total MobiFone: $mf"
echo "Total VinaPhone: $vn"
}
## Total MobiFone: 26
## Total VinaPhone: 33

Bài thực hành 3.2

Hãy viết hàm in ra dãy Fibonacci \(f\) từ thứ 1 đến thứ \(n\). Hàm có 1 tham số vào là một số nguyên dương \(n\). Dãy Fibonacci được mô tả như sau:

function fibo {
    let "$1"
    if (( $? > 0 )) ; then
        echo "Can dua vao so nguyen"
        return 1
    fi
    if (( $1 == 1 || $1 == 2 )) ; then
        echo 1
        return 0
    else
        x1=$(($1-1))
        x2=$(($1-2))
        y1=`fibo $x1`
        y2=`fibo $x2`
        echo $(($y1+$y2))
        return 0
    fi
}

fibo 10
## 55

Bài thực hành 3.3

Viết một script giải nén “vạn năng”: Script tự nhận dạng các phần mở rộng của tệp nén (ví dụ .zip, .gz, .7z…) và gọi đến các chương trình giải nén tương ứng.

file="$1"
ext=${file##*.} # Lấy phần mở rộng của file
case $ext in
    gz) echo "Use gunzip";;
    zip|ZIP) echo "Use zip";;
    7z) echo "Use 7z";;
    *) echo "Unknown extension";;
esac

Bài thực hành 3.4

Viết script có tên là saferm. Script này xóa file một cách an toàn, nghĩa là lệnh saferm myfile sẽ không xóa myfile mà chuyển myfile vào một thư mục ~/.TRASH. Các file trong ~/.TRASH sẽ bị xóa định kỳ sau 36 giờ. Tương ứng với saferm cần viết một script saferestore để khôi phục file nếu như bị file đó bị xóa nhầm. Mã nguồn của saferm:

bin=~/.TRASH
if [ -e "$bin" ] ; then
    mkdir "$bin"
elif [ ! -d "$bin ] ; then
    echo "$bin" is not a directory.
    echo "Please change name $bin file"
    exit 1
fi
# Move file to bin
mv $1 "$bin/."

Mã nguồn của cleanup (xóa định kỳ, cần được gọi đến bằng cron):

# Xóa các file sau 36 giờ = 1.5 * 24
find ~/.TRASH -ctime 1.5 -exec rm -f {} \;

Để khôi phục các file trong ~/.TRASH, cần có log file được tạo từ saferm ghi lại đường dẫn gốc.

Bài thực hành 3.5

Hãy viết một script quét các thư mục $HOME của người sử dụng nằm trong /home và tính tổng dung lượng lưu trữ của từng người sử dụng để kiểm soát quota. Script cần in ra dữ liệu có ba cột: tên người sử dụng, thư mục $HOME và dung lượng hiện đang sử dụng. Danh sách người sử dụng lấy trong /etc/passwd.

cut -d : -f 1,6 --output-delimiter ' ' /etc/passwd | grep /home | while read f1 f2 ; do
    echo $f1 $f2 `du -hc $f2 2> /dev/null | tail -1 |
    { IFS="\t" read num dir rest; echo $num; }`
done

Bài thực hành 3.6

Hãy liệt kê các thư mục rỗng trong một cây thư mục cho trước. Gợi ý: Sử dụng lệnh find.

# Tạo một thư mục rỗng
mkdir emptydir
find . -type d | while read line ; do
    nb=`ls $line|wc -l`
    if (( $nb == 0 )) ; then
        echo $line is empty
    fi
done
rmdir emptydir
## ./emptydir is empty
## ./xxx is empty

Bài thực hành 4.1

Hãy liệt kê tên các thư mục con của một thư mục bất kỳ

ls -l | grep ^d
## drwxrwxr-x 3 chau chau    4096 Oct 29 19:08 code
## drwxrwxr-x 2 chau chau    4096 Nov  5 12:17 docs
## drwxrwxr-x 2 chau chau    4096 Oct 24 09:26 images
## drwxrwxr-x 5 chau chau    4096 Oct  4 14:35 libraries
## drwxrwxr-x 2 chau chau    4096 Oct 26 22:39 old
## drwxrwxr-x 2 chau chau    4096 Nov  1 16:27 xxx

Bài thực hành 4.2

Hãy liệt kê các tiến trình “daemon” đang hoạt động trong hệ thống (các tiến trình có tên kết thúc bằng chữ d)

ps -ef | grep d$ | grep \? # Các tiến trình daemon không có tty, hay tty=?
## root       555     1  0 Nov01 ?        00:00:41 /usr/lib/systemd/systemd-journald
## root       597     1  0 Nov01 ?        00:00:01 /usr/lib/systemd/systemd-udevd
## root       801   789  0 Nov01 ?        00:00:02 /sbin/audispd
## root       814     1  0 Nov01 ?        00:00:22 /usr/lib/systemd/systemd-logind
## root       821     1  0 Nov01 ?        00:00:00 /usr/libexec/bluetooth/bluetoothd
## root       832     1  0 Nov01 ?        00:00:00 /usr/sbin/mcelog --ignorenodev --daemon --foreground
## root       833     1  0 Nov01 ?        00:00:11 /usr/sbin/irqbalance --foreground
## root       894     1  0 Nov01 ?        00:00:00 /usr/sbin/sshd
## colord     912     1  0 Nov01 ?        00:00:00 /usr/libexec/colord
## root      1209     1  0 Nov01 ?        00:00:07 /usr/libexec/upowerd
## root      1408     1  0 Nov01 ?        00:01:38 /usr/libexec/packagekitd
## chau      1627  1514  0 Nov01 ?        00:00:00 /usr/libexec/gvfsd
## root      1944     1  0 Nov01 ?        00:00:06 /usr/libexec/fwupd/fwupd
## chau      2025  1834  0 Nov01 ?        00:00:00 /usr/libexec/evolution-calendar-factory-subprocess --factory contacts --bus-name org.gnome.evolution.d
## chau      2079  2038  0 Nov01 ?        00:00:00 /usr/libexec/evolution-addressbook-factory-subprocess --factory local --bus-name org.gnome.evolution.d

Bài thực hành 4.3

Hãy liệt kê các dòng chứa số điện thoại của MobiFone trong tel.csv

cut -d , -f 2 tel.csv | grep -E '^090|^093' # Giả sử MobiFone có 2 đầu số 090, 093
## 0904394041
## 0936057869
## 0904215979
## 0904325898
## 0936696931
## 0936042468
## 0904122683
## 0904163326
## 0904273137
## 0904262456
## 0936676358
## 0934936850
## 0903212615
## 0903202759
## 0904261130
## 0904300181
## 09038698868
## 0904318199
## 0904100474
## 0904143433
## 0904984784
## 0936343996
## 0904252676
## 0903246274
## 0904429599
## 0906388688

Bài thực hành 4.4

Hãy tính tổng dung lượng lưu trữ và dung lượng rỗi của các file system có định dạng ext3 hoặc ext4

# Tổng dung lượng lưu trữ
df -T | grep -E 'ext3|ext4'|sed 's/ \{2,\}/ /g'|cut -d ' ' -f 4 | {
    total=0
    while read line ; do
        total=$(($total+$line))
    done
    echo Tổng dung lượng lưu trữ = $(($total/1024/1024)) GB
}
# Tổng dung lượng rỗi
df -T | grep -E 'ext3|ext4'|sed 's/ \{2,\}/ /g'|cut -d ' ' -f 5 | {
    total=0
    while read line ; do
        total=$(($total+$line))
    done
    echo Tổng dung lượng rỗi = $(($total/1024/1024)) GB
}
## Tổng dung lượng lưu trữ = 505 GB
## Tổng dung lượng rỗi = 42 GB

Bài thực hành 4.5

Sử dụng các ứng dụng ls, grep, cut để viết script liệt kê các symbolic link bị lỗi trong một thư mục. Để thử nghiệm, hãy tạo một số symbolic link lỗi bằng lệnh sau:

ln -s /tmp/sdfasd slink1

trong đó /tmp/sdfasd là một file không tồn tại.

rm -f slink1 docs/docs_slink1 slink2 2> /dev/null
# Tạo link lỗi
ln -s /tmp/sdfasd slink1
ln -s /tmp/sdfasd docs/docs_slink1
# Tạo link ok
ln -s code.html slink2
ls -lR | grep ^l
find | while read line ; do
    type=`file --mime-type "$line" | cut -d ' ' -f 2`
    if [ $type = "inode/symlink" ] ; then
        if [ ! -e $line ] ; then 
            echo "Symbolic link $line error"
        fi
    fi
done
## lrwxrwxrwx 1 chau chau      11 Nov  5 12:18 slink1 -> /tmp/sdfasd
## lrwxrwxrwx 1 chau chau       9 Nov  5 12:18 slink2 -> code.html
## lrwxrwxrwx 1 chau chau      11 Nov  5 12:18 docs_slink1 -> /tmp/sdfasd
## Symbolic link ./docs/docs_slink1 error
## Symbolic link ./slink1 error

Bài thực hành 5.1

Xóa 3 dòng đầu tiên của 1 file và đưa các dòng còn lại ra màn hình

cat test.txt
echo Thực hiện lệnh sed cho kết quả:
sed '1,3d' test.txt
## 1 Introduction
## 2
## 3 The sed stream editor is a text editor that performs editing operations on information  
## 4 coming from standard input or a file. Sed edits line-by-line and in a non-interactive way. 
## 5
## 6 This means that you make all of the editing decisions as you are calling the command and       
## 7 sed will execute the directions automatically. This may seem confusing or unintuitive,
## 8 but it is a very powerful and fast way to transform text.
## Thực hiện lệnh sed cho kết quả:
## 4 coming from standard input or a file. Sed edits line-by-line and in a non-interactive way. 
## 5
## 6 This means that you make all of the editing decisions as you are calling the command and       
## 7 sed will execute the directions automatically. This may seem confusing or unintuitive,
## 8 but it is a very powerful and fast way to transform text.

Bài thực hành 5.2

Hãy xóa các dòng trắng của một file và đưa các dòng còn lại ra màn hình

cat sedtext.txt
echo Xóa các dòng trắng:
# Dòng trắng là dòng không có ký tự nào,
# hoặc chỉ có các dấu cách/tab
sed '/^\s*$/d' sedtext.txt
## The history of Unix dates back to the mid-1960s   
## when the Massachusetts Institute of Technology,   
## AT&T Bell Labs, and General Electric were jointly   
## developing an experimental time sharing operating
## system called Multics for the GE-645 mainframe.[1]
## Multics introduced many innovations, but had many problems.
##     
## Bell Labs, frustrated by the size and complexity of Multics
## but not the aims, slowly pulled out of the project.
## Their last researchers to leave Multics, Ken Thompson, 
## Dennis Ritchie, Doug McIlroy, and Joe Ossanna among others,[2]
## decided to redo the work on a much smaller scale.[3]
## In 1979, Dennis Ritchie described their vision for Unix:[3]
## 
## What we wanted to preserve was not just a good environment in
## which to do programming, but a system around which a fellowship
## could form. We knew from experience that the essence of communal
## computing, as supplied by remote-access, time-shared machines,
## is not just to type programs into a terminal instead of a keypunch,
## but to encourage close communication.
## Xóa các dòng trắng:
## The history of Unix dates back to the mid-1960s   
## when the Massachusetts Institute of Technology,   
## AT&T Bell Labs, and General Electric were jointly   
## developing an experimental time sharing operating
## system called Multics for the GE-645 mainframe.[1]
## Multics introduced many innovations, but had many problems.
## Bell Labs, frustrated by the size and complexity of Multics
## but not the aims, slowly pulled out of the project.
## Their last researchers to leave Multics, Ken Thompson, 
## Dennis Ritchie, Doug McIlroy, and Joe Ossanna among others,[2]
## decided to redo the work on a much smaller scale.[3]
## In 1979, Dennis Ritchie described their vision for Unix:[3]
## What we wanted to preserve was not just a good environment in
## which to do programming, but a system around which a fellowship
## could form. We knew from experience that the essence of communal
## computing, as supplied by remote-access, time-shared machines,
## is not just to type programs into a terminal instead of a keypunch,
## but to encourage close communication.

Bài thực hành 5.3

Hãy tìm các dòng của file có ký tự trắng ở cuối dòng và in ra các dòng đó

sed -n '/ \{1,\}$/p' sedtext.txt
## The history of Unix dates back to the mid-1960s   
## when the Massachusetts Institute of Technology,   
## AT&T Bell Labs, and General Electric were jointly   
##     
## Their last researchers to leave Multics, Ken Thompson,

Bài thực hành 5.4

Hãy thay thế từ Multics (không phân biệt chữ hoa/thường) bằng MULTICS trong file sedtext.txt

sed 's/Multics/MULTICS/gI' sedtext.txt
## The history of Unix dates back to the mid-1960s   
## when the Massachusetts Institute of Technology,   
## AT&T Bell Labs, and General Electric were jointly   
## developing an experimental time sharing operating
## system called MULTICS for the GE-645 mainframe.[1]
## MULTICS introduced many innovations, but had many problems.
##     
## Bell Labs, frustrated by the size and complexity of MULTICS
## but not the aims, slowly pulled out of the project.
## Their last researchers to leave MULTICS, Ken Thompson, 
## Dennis Ritchie, Doug McIlroy, and Joe Ossanna among others,[2]
## decided to redo the work on a much smaller scale.[3]
## In 1979, Dennis Ritchie described their vision for Unix:[3]
## 
## What we wanted to preserve was not just a good environment in
## which to do programming, but a system around which a fellowship
## could form. We knew from experience that the essence of communal
## computing, as supplied by remote-access, time-shared machines,
## is not just to type programs into a terminal instead of a keypunch,
## but to encourage close communication.

Bài thực hành 5.5

Hãy đếm tần suất các từ xuất hiện trong một file text và in ra các từ kèm theo tần suất tương ứng (Lưu ý không phân biệt chữ hoa/thường)

# Tùy chọn -i của uniq không phân biệt chữ hoa, thường với các từ
sed 's/[ \.,;:]/\n/g' sedtext.txt | sed '/^\s*$/d' | sort | uniq -i -c | sort -n
##       1 [1]
##       1 1979
##       1 [2]
##       1 aims
##       1 among
##       1 an
##       1 around
##       1 as
##       1 AT&T
##       1 back
##       1 called
##       1 close
##       1 communal
##       1 communication
##       1 complexity
##       1 computing
##       1 could
##       1 dates
##       1 decided
##       1 described
##       1 developing
##       1 do
##       1 Doug
##       1 Electric
##       1 encourage
##       1 environment
##       1 essence
##       1 experience
##       1 experimental
##       1 fellowship
##       1 form
##       1 from
##       1 frustrated
##       1 GE-645
##       1 General
##       1 good
##       1 had
##       1 history
##       1 innovations
##       1 instead
##       1 Institute
##       1 into
##       1 introduced
##       1 is
##       1 Joe
##       1 jointly
##       1 Ken
##       1 keypunch
##       1 knew
##       1 last
##       1 leave
##       1 machines
##       1 mainframe
##       1 Massachusetts
##       1 McIlroy
##       1 mid-1960s
##       1 much
##       1 on
##       1 operating
##       1 Ossanna
##       1 others
##       1 out
##       1 preserve
##       1 problems
##       1 programming
##       1 programs
##       1 project
##       1 pulled
##       1 redo
##       1 remote-access
##       1 researchers
##       1 scale
##       1 sharing
##       1 size
##       1 slowly
##       1 smaller
##       1 supplied
##       1 Technology
##       1 terminal
##       1 that
##       1 Thompson
##       1 time
##       1 time-shared
##       1 type
##       1 vision
##       1 wanted
##       1 was
##       1 were
##       1 What
##       1 when
##       1 work
##       2 [3]
##       2 Bell
##       2 by
##       2 Dennis
##       2 for
##       2 in
##       2 just
##       2 Labs
##       2 many
##       2 Ritchie
##       2 system
##       2 their
##       2 Unix
##       2 we
##       2 which
##       3 and
##       3 not
##       4 but
##       4 Multics
##       6 a
##       6 of
##       7 to
##       9 the

Bài thực hành 6.1

Chuyển khuôn dạng của tel.csv sang dạng XML với các cặp thẻ tương ứng: <stt></stt>, <dienthoai></dienthoai>, <hoten></hoten>, <chucdanh></chucdanh><coquan></coquan>

awk '
BEGIN {FS=","}
{
    printf("<stt>%s</stt><dienthoai>%s</dienthoai><hoten>%s</hoten><chucdanh>%s</chucdanh><coquan>%s</coquan>\n",
    $1, $2, $3, $4, $5);
}
' tel.csv | head -6
## <stt>1</stt><dienthoai>08485876443</dienthoai><hoten>"KIM Van Chien"</hoten><chucdanh></chucdanh><coquan>"a"</coquan>
## <stt>2</stt><dienthoai>0912025544</dienthoai><hoten>"Đỗ Thị Phi Nga"</hoten><chucdanh>"Giảng viên chính Thạc sỹ"</chucdanh><coquan>"Khoa Sư phạm Tiếng Anh/Faculty of English"</coquan>
## <stt>3</stt><dienthoai>0983669908</dienthoai><hoten>"Bùi Minh Đức"</hoten><chucdanh>"Thạc Sỹ"</chucdanh><coquan>"Khoa Công nghệ Thông tin"</coquan>
## <stt>4</stt><dienthoai>0949844646</dienthoai><hoten>"Bùi Thu Hà"</hoten><chucdanh>"Tiến sĩ"</chucdanh><coquan>"Khoa Sinh Học"</coquan>
## <stt>5</stt><dienthoai>01648462188</dienthoai><hoten>"bui thuy dung"</hoten><chucdanh></chucdanh><coquan></coquan>
## <stt>6</stt><dienthoai>0904394041</dienthoai><hoten>"Bùi Tiến Long"</hoten><chucdanh></chucdanh><coquan>"Trung tâm Thông tin - Thư viện"</coquan>

Bài thực hành 6.2

Cho file live.txt có nội dung tường thuật bóng đá, trong đó mỗi sự kiện được viết trên một paragraph Hãy tường thuật nội dung theo thứ tự ngược lại.

cat live.txt
## 0h40': CĐV xếp hàng vào khu vực fanzone và có rất
## đông cảnh sát xuất hiện tại nơi này. (Ảnh: Minh Hạnh)
## 
## 
## 
## 
## 0h15': Theo Daily Mail, một tiếng nổ lớn đã phát ra vào khoảng 5h30
## (giờ địa phương). Đây là một vụ nổ được đội phá bom thực hiện một
## cách chủ động nhằm vô hiệu hóa mối nguy hiểm từ túi đồ khả nghi
## đặt ngay gần xe buýt chở đội tuyển Pháp chuẩn bị tới sân vận động Stade de France.
## 
## 0h10': CĐV xếp hàng vào fanzone từ giữa trưa để chờ đến 16h00
## (giờ địa phương) mới được vào đấu. Và phía dưới có hình ảnh
## bảng dự đoán trận chung kết của phóng viên các nơi. (Ảnh: Minh Hạnh)
## 
## 
## 
## 23h59': Tờ Diario de Noticias của Bồ Đào Nha mới đây đã đưa ra
## bằng chứng cho thấy tiền vệ trẻ Renato Sanches không hề gian
## lận tuổi như những lời đồn đoán xuất hiện thời gian qua. Theo đó,
## đúng là tài năng trẻ người Bồ Đào Nha sinh ngày 18/8/1997.
## Nhờ có tấm giấy khai sinh nói trên,
## Sanches đương nhiên được công nhận là 18 tuổi,
## nghĩa là không ai có thể bác bỏ danh hiệu cầu thủ trẻ nhất
## góp mặt ở một trận bán kết EURO mà anh mới có được.
##   
## 
## 23h52': Với 3 pha lập công ở EURO 2016,
## Ronaldo đã có 9 bàn ở các VCK EURO. Chỉ cần ghi thêm 1 bàn nữa,
## anh sẽ vượt qua huyền thoại người Pháp Michel Platini
## để trở thành cầu thủ "nổ súng" nhiều nhất ở giải vô địch châu Âu.
awk 'BEGIN {RS="\n\n"}
{ line[NR] = $0}
END {
    for (i=NR;i>0;i--)
        print line[i]
}' live.txt
## 
## 
## 23h52': Với 3 pha lập công ở EURO 2016,
## Ronaldo đã có 9 bàn ở các VCK EURO. Chỉ cần ghi thêm 1 bàn nữa,
## anh sẽ vượt qua huyền thoại người Pháp Michel Platini
## để trở thành cầu thủ "nổ súng" nhiều nhất ở giải vô địch châu Âu. 
## 23h59': Tờ Diario de Noticias của Bồ Đào Nha mới đây đã đưa ra
## bằng chứng cho thấy tiền vệ trẻ Renato Sanches không hề gian
## lận tuổi như những lời đồn đoán xuất hiện thời gian qua. Theo đó,
## đúng là tài năng trẻ người Bồ Đào Nha sinh ngày 18/8/1997.
## Nhờ có tấm giấy khai sinh nói trên,
## Sanches đương nhiên được công nhận là 18 tuổi,
## nghĩa là không ai có thể bác bỏ danh hiệu cầu thủ trẻ nhất
## góp mặt ở một trận bán kết EURO mà anh mới có được.
##   
## 
## 0h10': CĐV xếp hàng vào fanzone từ giữa trưa để chờ đến 16h00
## (giờ địa phương) mới được vào đấu. Và phía dưới có hình ảnh
## bảng dự đoán trận chung kết của phóng viên các nơi. (Ảnh: Minh Hạnh)
## 
## 0h15': Theo Daily Mail, một tiếng nổ lớn đã phát ra vào khoảng 5h30
## (giờ địa phương). Đây là một vụ nổ được đội phá bom thực hiện một
## cách chủ động nhằm vô hiệu hóa mối nguy hiểm từ túi đồ khả nghi
## đặt ngay gần xe buýt chở đội tuyển Pháp chuẩn bị tới sân vận động Stade de France.
## 
## 0h40': CĐV xếp hàng vào khu vực fanzone và có rất
## đông cảnh sát xuất hiện tại nơi này. (Ảnh: Minh Hạnh)

Bài thực hành 6.3

Viết một script đưa ra màn hình thông tin về các tiến trình đang có trong hệ thống với khuôn dạng nhiều dòng, mỗi dòng có các trường phân cách bởi dấu trắng:

#!/bin/bash
ps -ef|awk 'NR>1 {printf("%d %d\n", $3, $2);}' | sort -n |  awk '
BEGIN { ppid = -1 }
{
    if ($1 != ppid) {
        if (ppid == -1) printf("%d %d", $1, $2)
        else printf("\n%d %d", $1, $2);
        ppid = $1
    }
    else printf(",%d", $2)
}
END {printf("\n");}
'
## 0 1,2
## 1 1053,1102,1209,1310,1372,1396,1408,1514,1530,1659,1692,1699,1755,1944,1973,20212,2056,2144,555,597,758,759,789,814,815,816,821,824,825,831,832,833,839,843,853,861,876,885,886,888,890,891,894,906,912,923,9436
## 2 10,10246,104,105,106,107,108,109,11,111,112,113,114,115,116,117,11705,118,12,126,128,129,13,13109,13531,13752,13829,13875,13891,139,13928,14,14045,141,14372,144,15,16,1684,17,18,181,18547,18966,18968,18977,18978,18982,19085,20,21,22,23,23029,24,25,26,28,29,3,30,30599,31,31029,32,33,34,36,364,366,37,371,375,38,39,40,41,42,43,433,435,44,444,446,45,46,465,466,47,48,49,5,50,51,52,54,57,58,587,588,635,675,7,710,711,763,764,772,773,8,8567,9
## 789 801
## 801 804
## 853 19032
## 885 1138,1172,1173,1192,1195,1198,1201
## 888 1299,1510
## 906 1044,1045,1046,1047,1048,943
## 1299 1316
## 1310 1311,1340,1344,1355
## 1316 1318,1336
## 1336 1363,1414
## 1344 1353
## 1363 1389
## 1389 1393,1472
## 1510 1533
## 1514 1518,1553,1593,1600,1627,1629,1634,1691,1713,1715,1720,1742,17751,1780,1782,1790,1794,1799,18202,1834,2038,2620,3201,3212,3225,3284
## 1533 1537,1542
## 1542 1588,1821,1870,1874,1899,1908,1909,1910,1929,1946
## 1593 1598
## 1692 1697,1840,2212
## 1834 2025,2036
## 2038 2079
## 7610 7646
## 7646 28018
## 17751 17760,3105,7610
## 28018 28019
## 28019 28020,28021,28022,28023

Bài thực hành 6.4

Sử dụng lệnh free -m để lấy thông tin về bộ nhớ đang sử dụng của máy tính trong 5 phút với tần suất 5 giây/lần In ra các giá trị sau: Tổng dung lượng bộ nhớ; min, max, trung bình \(\mu\) và độ lệch chuẩn \(\sigma=\sqrt{\frac{(x-\mu)^2}{N-1}}\) của bộ nhớ đang sử dụng.

# Output của lệnh free
free -m
# chúng ta cần lấy tham số về tổng bộ nhớ và bộ nhớ rỗi ở dòng thứ 2
# Mã lệnh lấy bộ nhớ định kỳ (sẽ được gọi bởi cron với tần suất 5 giây/lần)
free -m | awk 'NR==2 {print $2, $3}' >> mem.log
# Mã lệnh lấy 60 bản ghi cuối cùng của mem.log và thống kê
tail -60 mem.log | awk '
BEGIN {
    max = 0
    total = 0
}
{
    val[NR] = $2
    if (NR == 1) min = $2
    else if (min > $2) min = $2
    if (max < $2) max = $2
    mean += $2
    total = $1
}
END {
    mean /= NR
    std = 0
    for (i=1;i<=NR;i++)
        std += (val[i]-mean)**2
    std = sqrt(std/(NR-1))
    printf("Total memory %d, min used %d mean used %.1f max used %d standard deviation %.1f\n",
    $1, min, mean, max, std)
}
'
##               total        used        free      shared  buff/cache   available
## Mem:           3816        2591         162          22        1062         861
## Swap:          3855        1835        2020
## Total memory 3816, min used 1942 mean used 2140.2 max used 2608 standard deviation 244.2

Cho file grepdata.txt:

head -6 grepdata.txt
## Sep. 17, 2013
## Esperanza High School
## 1830 N. Kellog Dr.
## Anaheim, CA 92807-1281
## Steve Marshal
## 714-555-7870 X7310

Bài thực hành 7.1

Hãy tìm các số điện thoại có dạng ddd-ddd-dddd trong file

grep '[0-9]\{3\}-[0-9]\{3\}-[0-9]\{4\}' grepdata.txt
## 714-555-7870 X7310
## 714-555-7870 x7309
## 562-555-9800
## 562-555-1281
## 310-555-4412
## 714-555-5350 x2134

Bài thực hành 7.2

Hãy tìm các số điện thoại có dạng ddd-ddd-dddd và có extension (ví dụ x1234)

grep '[0-9]\{3\}-[0-9]\{3\}-[0-9]\{4\} \{1,\}X[0-9]\{4\}' grepdata.txt
## 714-555-7870 X7310

Bài thực hành 7.3

Hãy sử dụng biểu thức chính qui và sed để chuyển một file có nhiều dòng dài (longline.txt) thành file có các dòng với độ dài nhỏ hơn hoặc bằng một giá trị cho trước, chẳng hạn 70 ký tự

cat longline.txt
## The history of Unix dates back to the mid-1960s when the Massachusetts Institute of Technology, AT&T Bell Labs, and General Electric were jointly developing an experimental time sharing operating system called Multics for the GE-645 mainframe.[1] Multics introduced many innovations, but had many problems.
## 
## Bell Labs, frustrated by the size and complexity of Multics but not the aims, slowly pulled out of the project. Their last researchers to leave Multics, Ken Thompson, Dennis Ritchie, Doug McIlroy, and Joe Ossanna among others,[2] decided to redo the work on a much smaller scale.[3] In 1979, Dennis Ritchie described their vision for Unix:[13]
## 
##     What we wanted to preserve was not just a good environment in which to do programming, but a system around which a fellowship could form. We knew from experience that the essence of communal computing, as supplied by remote-access, time-shared machines, is not just to type programs into a terminal instead of a keypunch, but to encourage close communication.
## aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
sed 's/\(.\{1,69\}\)\( \)/\0\n/g' longline.txt
## The history of Unix dates back to the mid-1960s when the 
## Massachusetts Institute of Technology, AT&T Bell Labs, and General 
## Electric were jointly developing an experimental time sharing 
## operating system called Multics for the GE-645 mainframe.[1] Multics 
## introduced many innovations, but had many 
## problems.
## 
## Bell Labs, frustrated by the size and complexity of Multics but not 
## the aims, slowly pulled out of the project. Their last researchers to 
## leave Multics, Ken Thompson, Dennis Ritchie, Doug McIlroy, and Joe 
## Ossanna among others,[2] decided to redo the work on a much smaller 
## scale.[3] In 1979, Dennis Ritchie described their vision for 
## Unix:[13]
## 
##     What we wanted to preserve was not just a good environment in 
## which to do programming, but a system around which a fellowship could 
## form. We knew from experience that the essence of communal computing, 
## as supplied by remote-access, time-shared machines, is not just to 
## type programs into a terminal instead of a keypunch, but to encourage 
## close 
## communication.
## aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Bài thực hành 7.4

Hãy tìm các số điện thoại dạng dddddddddd trong file tel.csv và in ra nhóm ddd bắt đầu từ vị trí thứ 4 (vị trí đầu là 1)

# 6 dòng đầu tiên của tel.csv
head -6 tel.csv
# 6 dòng đầu tiên của tel.csv sau khi xử lý
cut -d , -f 2 tel.csv |
sed -n 's/\([0-9]\{3\}\)\([0-9]\{3\}\)\([0-9]\{4\}\)/\1 \2 \3/p' |
cut -d ' ' -f 2  | head -6
## 1,08485876443,"KIM Van Chien",,"a"
## 2,0912025544,"Đỗ Thị Phi Nga","Giảng viên chính Thạc sỹ","Khoa Sư phạm Tiếng Anh/Faculty of English"
## 3,0983669908,"Bùi Minh Đức","Thạc Sỹ","Khoa Công nghệ Thông tin"
## 4,0949844646,"Bùi Thu Hà","Tiến sĩ","Khoa Sinh Học"
## 5,01648462188,"bui thuy dung",,
## 6,0904394041,"Bùi Tiến Long",,"Trung tâm Thông tin - Thư viện"
## 858
## 202
## 366
## 984
## 484
## 439

Bài thực hành 7.5

Hãy thay đổi tham chiếu [1], [2]… trong một file thành tham chiếu dạng LaTeX \cite{1}, \cite{2}…

# Đổi file từ dòng dài sang dòng ngắn hơn 70 ký tự cho dễ đọc
sed 's/\(.\{1,69\}\)\( \)/\0\n/g' longline.txt > tmp.txt
sed 's/\(\[\)\([0-9]\+\)\(\]\)/\\cite{\2}/g' tmp.txt
## The history of Unix dates back to the mid-1960s when the 
## Massachusetts Institute of Technology, AT&T Bell Labs, and General 
## Electric were jointly developing an experimental time sharing 
## operating system called Multics for the GE-645 mainframe.\cite{1} Multics 
## introduced many innovations, but had many 
## problems.
## 
## Bell Labs, frustrated by the size and complexity of Multics but not 
## the aims, slowly pulled out of the project. Their last researchers to 
## leave Multics, Ken Thompson, Dennis Ritchie, Doug McIlroy, and Joe 
## Ossanna among others,\cite{2} decided to redo the work on a much smaller 
## scale.\cite{3} In 1979, Dennis Ritchie described their vision for 
## Unix:\cite{13}
## 
##     What we wanted to preserve was not just a good environment in 
## which to do programming, but a system around which a fellowship could 
## form. We knew from experience that the essence of communal computing, 
## as supplied by remote-access, time-shared machines, is not just to 
## type programs into a terminal instead of a keypunch, but to encourage 
## close 
## communication.
## aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Bài thực hành 7.6

Tải nội dung của một trang web và in ra danh sách các ảnh của trang web có trong thẻ <img> Sử dụng ứng dụng wget để tải nội dung trang web.

wget http://vnexpress.net -O vnex.txt 2> /dev/null > /dev/null
sed 's/<img[^>]\{1,\}>/\n\0\n/gI' vnex.txt  | grep '<img' |
sed 's/\(<img.\{1,\}src="\)\([^"]\{1,\}\)\("\)/\n\2\n/gI'  | grep -i http | head -10
## http://b.scorecardresearch.com/p?c1=2&c2=19747654&cv=2.0&cj=1
## http://st.f1.vnecdn.net/responsive/i/v29/graphics/img_blank.gif
## http://st.f1.vnecdn.net/responsive/i/v32/graphics/logo.png
## http://st.f1.vnecdn.net/responsive/i/v32/graphics/img_logo_home.gif
## http://st.f1.vnecdn.net/responsive/i/v32/icons/icon_videomenu.gif
## http://st.f1.vnecdn.net/responsive/i/v32/graphics/img_logo_vne_web.gif
## http://st.f1.vnecdn.net/responsive/i/v32/graphics/img_blank.gif
## http://st.f3.vnecdn.net/responsive/c/v58/images/graphics/img_rss_2.gif
## http://img.f27.kinhdoanh.vnecdn.net/2016/11/05/VuDinhDuy91531478179866-1478318725_490x294.jpg
## http://st.f1.vnecdn.net/responsive/i/v15/graphics/img_blank.gif