1

给定一个文本文件 file.txt,请只打印这个文件中的第十行。

示例:

假设 file.txt 有如下内容:

Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10

你的脚本应当显示第十行:

Line 10

解:

sed -n '10p' file.txt

-n 指除了第十行都不打印

awk 'NR == 10' file.txt

NRawk 内置的一个变量,表示当前处理的行号(行号从1开始)。这个模式表示如果当前行号等于10,则匹配成功。

tail -n +10 file.txt | head -1

tail -n +10 从文件的第十行开始打印,head -1 从头开始打印一行

2

给定一个包含电话号码列表(一行一个电话号码)的文本文件 file.txt,写一个单行 bash 脚本输出所有有效的电话号码。

你可以假设一个有效的电话号码必须满足以下两种格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一个数字)

你也可以假设每行前后没有多余的空格字符。

示例:

假设 file.txt 内容如下:

987-123-4567
123 456 7890
(123) 456-7890

你的脚本应当输出下列有效的电话号码:

987-123-4567
(123) 456-7890

解:

grep -E '^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$' file.txt

-E 启用正则表达式

  • ^: 匹配行的开始。

  • \(: 匹配左括号 (

  • [0-9]{3}: 匹配三个数字。

  • \) 或者 ``: 匹配右括号 ) 或者空格。

  • | 表示或者

    (\([0-9]{3}\) |[0-9]{3}-)
  • [0-9]{3}: 匹配三个数字。

  • -: 匹配短横线 -

  • [0-9]{4}: 匹配四个数字。

  • $: 匹配行的结尾。

3

给定一个文件 file.txt,转置它的内容。

你可以假设每行列数相同,并且每个字段由 ' ' 分隔。

示例:

假设 file.txt 文件内容如下:

name age
alice 21
ryan 30

应当输出:

name alice ryan
age 21 30

解:

columns=$(cat file.txt | head -n 1 | wc -w)
for i in $(seq 1 $columns)
do
awk '{print $'$i'}' file.txt | xargs
done

wc -w 统计单词数

$(seq 1 $columns) 表示循环列数,seq用于生成1-seq的数字,seq 1表示生成数字1

awk ‘{print $’$i’}’ 是一个动态引用,print $i 表示打印每行的第几个字段

xargs 逐列将每列转换为行。但是这里我们只需要每次取一列所以需要前置处理

4

写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的

频率

为了简单起见,你可以假设:

  • words.txt只包括小写字母和 ' '
  • 每个单词只由小写字母组成。
  • 单词间由一个或多个空格字符分隔。

示例:

假设 words.txt 内容如下:

the day is sunny the the
the sunny is is

你的脚本应当输出(以词频降序排列):

the 4
is 3
sunny 2
day 1

说明:

  • 不要担心词频相同的单词的排序问题,每个单词出现的频率都是唯一的。
  • 你可以使用一行 Unix pipes 实现吗?

解:

awk '{for(i=1; i<=NF; i++) {count[$i]++;}} END {for(word in count) {print word, count[word];}}' words.txt | sort -k2,2nr

awk可以逐行读取每行的单词,NF表示每行的字段数,以单词($i)作为索引来建立计数数组

sort -k2,2nr 对输入进行排序。具体参数含义如下:

  • -k2,2nr 表示按照第二列(单词出现的次数)进行逆序排序。2,2表示从第二列到第二列
  • -n 表示按照数值大小排序。
  • -r 表示逆序排序。
cat words.txt | tr -s ' ' '\n' | sort | uniq -c | sort -r | awk '{ print $2, $1 }' 
  1. tr -s ' ' '\n'tr 命令用于字符替换,-s ' ' 表示将多个连续的空格字符替换成一个空格,'\n' 表示将空格替换成换行符,因此这一步将文本中的空格分隔的单词转换成每行一个单词的形式。
  2. sort:对单词进行排序。
  3. uniq -cuniq 命令用于去除连续重复的行,-c 选项会显示每行重复出现的次数。因此,这一步会统计每个单词出现的次数。
  4. sort -r:对统计结果按照出现次数进行逆序排序。