题目:
Given a text file file.txt
, transpose its content.
You may assume that each row has the same number of columns and each field is separated by the ' '
character.
For example, if file.txt
has the following content:
name age alice 21 ryan 30
Output the following:
name alice ryan age 21 30第一次尝试:
1
2
3
4
5
6
7
8
|
# Read from the file file.txt
and
print
its transposed content to stdout.
n=`awk
'{print NF}'
file.txt | head -n1`
for
((i=1;i<=
$n
;i++))
do
a=`
echo
$i
`;
awk
'{print $'
$a
'}'
file.txt | tr
'\n'
' '
;
printf
"\012"
;
done
|
思想:
(1)得出file.txt有多少列,将列数赋给n
(2)for循环,每次处理一列,使用awk命令取出一列,然后将回车换行符\n替换为空格,在最后加一个回车换行("\012"),即完成了一列的转置
结果报错:
虽然结果正确,但是确实程序有些复杂,内存超了。。。
由于实在想不出什么其他好方法,就去OJ讨论区搜了一下,找到了一种accepted方法
OJ讨论区的一种解答:
1
2
3
4
5
6
7
8
|
cat file.txt | awk '{
for
(i=1;i<=NF;++i) {
arr[i] = arr[i]
$i
" "
;
}
}
END
{
for
(i=1;i<=NF;++i)
print
substr
(arr[i], 0, length(arr[i])-1)
}'
|
思想:
(1)简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
NF是指file.txt中的列数。
(2)假设i等于第n列时,
arr[i] = arr[i]
$i
" "
; 表示awk命令对第n行逐行读入,
假设第n行为:aa
bb
cc
则先读入第一行,即aa。然后将第一行aa赋给数组arr[i],也即arr[n]。后面再加一个" ",即空格。然后第二行重新执行同样的操作。
结果为:
-
第一行 aa空格 第二行 aa空格bb空格 第三行 aa空格bb空格cc空格
所以
arr[i] = arr[i]
$i
" "
;的
最终结果为arr[i]=
aa空格bb空格cc空格
(3)awk使用方法
awk '{pattern + action}' {filenames}
其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。BEGIN会先执行,在输入文件之前执行。END在输入文件关闭后awk退出之前执行。
接下来只要将arr数组(arr[1],……,arr[NF])的元素输出即可。所以END后面还需要一个循环,但是注意每个“arr[i]=aa空格bb空格cc空格”的末尾多出一个空格,所以需要在输出时不显示最后一个空格,因此用到
substr
(arr[i], 0, length(arr[i])-1)。
本题知识点:
1、awk的用法
2、数组的用法