0

我有一个大文件,需要根据行号进行分割。例如,我的文件是这样的:

aaaaaa 
bbbbbb  
cccccc
dddddd
****** //here blank line//
eeeeee
ffffff
gggggg
hhhhhh
*******//here blank line//
ıııııı
jjjjjj
kkkkkk
llllll
******
//And so on...

我需要两个单独的文件,这样一个文件应该有前 4 行,第三个 4 行,第五个 4 行,另一个文件应该有第二个 4 行,第四个 4 行,第六个 4 行,依此类推。我怎样才能在 bash 脚本中做到这一点?

4

5 回答 5

2

你可以玩线号,NR

$ awk 'NR%10>0 && NR%10<5' your_file > file1
$ awk 'NR%10>5' your_file > file2
  • 如果是10K + n, 0 < n < 5,则转到第一个文件。
  • 如果是10K + n, n > 5,则转到第二个文件。

在一行中:

$ awk 'NR%10>0 && NR%10<5 {print > "file1"} NR%10>5 {print > "file2"}' file

测试

$ cat a
1
2
3
4

6
7
8
9

11
12
13
14

16
17
18
19

21
22
23
24

26
27
28
29

31
32
33
34

36
37
38
39

41
42
43
44

46
47
48
49

51
$ awk 'NR%10>0 && NR%10<5 {print > "file1"} NR%10>5 {print > "file2"}' a
$ cat file1
1
2
3
4
11
12
13
14
21
22
23
24
31
32
33
34
41
42
43
44
51
$ cat file2
6
7
8
9
16
17
18
19
26
27
28
29
36
37
38
39
46
47
48
49
于 2013-10-02T11:05:42.397 回答
1

您可以使用headand来执行此操作tail(它们不是 bash 本身的一部分):

head -n 20 <file> | tail -n 5

给你第 15 到 20 行。

但是,如果您想获取文件的多个部分,则效率很低,因为必须一次又一次地对其进行解析。在这种情况下,我更喜欢一些真正的脚本。

于 2013-10-02T11:05:02.650 回答
1

另一种方法是将空行分隔的段落视为记录,并将奇数和偶数记录打印到不同的文件中:

awk -v RS= -v ORS='\n\n' '{
    outfile = (NR % 2 == 1) ? "file1" : "file2"
    print > outfile
}' file
于 2013-10-02T14:59:37.183 回答
0

也许是这样的:

#!/bin/bash

EVEN="even.log"
ODD="odd.log"

line_count=0
block_count=0
while read line
do
    # ignore blank lines
    if [ ! -z "$line" ]; then
      if [ $(( $block_count % 2 )) -eq 0 ]; then
        # even
        echo "$line" >> "$EVEN"
      else
        # odd
        echo "$line" >> "$ODD"
      fi
      line_count=$[$line_count +1]
      if [ "$line_count" -eq "4" ]; then
        block_count=$[$block_count +1]
        line_count=0
      fi
    fi
done < "$1"

第一个参数是源文件:./split.sh split_input

于 2013-10-02T11:24:39.143 回答
0

此脚本打印文件 1.txt 中索引为 0、1、2、3、8、9、10、11、16、17、18、19 的行

i=0
while read p; do
  if [ $i%8 -lt 4 ]
  then
    echo $p
  fi
  let i=$i+1
done < 1.txt

此脚本打印索引为 4, 5, 6, 7, 12, 13, 14, 15, ...

i=0
while read p; do
  if [ $i%8 -gt 3 ]
  then
    echo $p
  fi
  let i=$i+1
done < 1.txt
于 2013-10-02T11:16:05.450 回答