转置文件¶
描述¶
给定一个文件 file.txt,转置它的内容。
你可以假设每行列数相同,并且每个字段由 ' ' 分隔。
示例
输入:file.txt
name age
alice 21
ryan 30
name alice ryan
age 21 30
题解¶
分析¶
这道题要是用matlab
那就是一步到位,不过用shell
也不难,只要完成以下两步即可。
- 获取文件的列数
- 按列读取文件,并按行输出
实现1¶
wc
可以获取文件的行数、单词数和字符数,由于文件按二维数组形式存储,所以列数就等于单词数除以行数 words / lines
。
wc file.txt
的输出格式为lines words chars file.txt
, 然后通过awk
计算 words 与 lines 相除之商就是行数。
知道了列数,接下来就是按列输出,cut -d' ' -f $i file.txt
可以打印按空格分隔的第 i 列,使用echo直接输出便是按行输出了。
# Read from the file file.txt and print its transposed content to stdout.
# 1. 获取列数
col=$(wc file.txt | awk '{print $2 / $1}')
# 2. 按列打印
for i in `seq 1 $col`
do
echo `cut -d' ' -f $i file.txt`
done
echo 不加引号
此处echo不对输出内容加引号,就会在输出时自动将换行符\n
替换为空格
实现2¶
对于按列读取,也可以使用awk {print $i}
打印第 i 列,然后通过xargs
按行输出
# Read from the file file.txt and print its transposed content to stdout.
# 1. 获取列数
col=$(wc file.txt | awk '{print $2 / $1}')
# 2. 按列打印
for i in `seq 1 $col`
do
awk -v col="$i" '{print $col}' file.txt |xargs
done
awk 使用变量
awk
调用shell
变量有点麻烦,可以通过-v name="$var"
定义awk可用的变量
实现3¶
对于获取列数,除了以上方法外,还可以通过head
结合wc
,读取首行文本并计算单词数
col=$(head -1 file.txt | wc -w)
当然,head
可以,tail
自然也行,就不赘述了。
小结¶
本题主要考察文件读写操作,涉及指令主要包括echo
, awk
, wc
,head
, xargs
.
运用到的两个小技巧:
- echo 不加引号会自动将换行符转为空格
- awk 通过
-v name="$var"
可以调用 shell 变量