AWK-将多个.dat文件的第二行输出到一个文件


9

我有多个文件,例如:(实际上我有80个)

file1.dat

2 5

6 9

7 1

file2.dat

3 7

8 4

1 3

我想最后得到一个包含所有第二行的文件。即

output.dat

6 9

8 4

到目前为止,我所拥有的内容虽然循环了文件名,但是之前覆盖了文件。例如上述文件的输出将只是

8 4

我的shell脚本看起来像这样:

post.sh

TEND = 80

TINDX = 0

while [ $TINDX - lt $TEND]; do

awk '{ print NR==2 "input-$TINDX.dat > output.dat

TINDX = $((TINDX+1))

done

Answers:


17

删除while循环并使用shell括号扩展以及FNR一个内置awk变量:

awk 'FNR==2{print $0 > "output.dat"}' file{1..80}.dat

9
甚至更短awk 'FNR==2' file{1..80}.dat > output.dat
Archemar

7

head -n 2 input.dat | tail -n 1 | awk……


是的,head/ tail绝对是一种选择,那么您不需要awk
jimmij 2015年

7

sed 就足够了:

sed -sn 2p file{1..80}.dat > output.dat

-s 选项需要从每个文件打印第二行,否则仅打印第一文件的第二行。


2

aragaer的sed解决方案是最好的,是的。但是,由于我确实喜欢head|tail剪切,所以我有一个head|tail支持多个文件的解决方案,而不仅仅是单个文件input.dat。使用for循环,而不是传递要sed的文件列表,还可以更轻松地在提取sed的第二行之前/之后对文件执行其他操作。

# empty output.dat first
rm output.dat

# have a one-liner
for file in *.dat; do head -2 $file | tail -1 >> output.dat; done 

评论丰富的多行版本:

注意:下面的代码将运行。我们可以自由地把断行后|&&或者||,继续我们对下一行命令; 我们甚至可以在两者之间添加评论。我花了很多不知道这一点(也没有真正在任何地方看到它)。这种样式在交互式提示时不太有用,但会无休止地清理脚本文件。

# empty output.dat first
rm output.dat

for file in *.dat; do
    # file -> lines 1 and 2 of file
    head -2 $file |
    # lines 1 and 2 of file -> line 2 of file >> appended to output.dat
    tail -1 >> output.dat
done

0

显然有很多方法可以做到这一点-我认为我最喜欢@aragaer的sed答案

这是一个纯粹使用bash内置函数的程序,不需要派生任何外部实用程序:

for f in file{1..80}.dat; do
    { read && read && printf "%s\n" "$REPLY"; } < "$f"
done > output.dat

0

为了在多个文件上高效地使用awksed回答问题,最好使用nextfile语句来跳过中处理不需要的行awk

awk 'FNR==2{ print >"output.dat"; nextfile}' infile{1..80}.dat

使用sed,我们可以在第三行处理时退出并sed处理下一个文件。

sed -sn '2p;3q' infile{1..80}.dat > output.dat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.