Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 根据行号将一个文件划分为单独的文件_Bash_Awk - Fatal编程技术网

Bash 根据行号将一个文件划分为单独的文件

Bash 根据行号将一个文件划分为单独的文件,bash,awk,Bash,Awk,我有以下测试文件: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 我希望以一种方式将其分开,即每个文件都包含上一个文件的最后一行作为第一行。例如: file 1: 1 2 3 4 5 file2: 5 6 7 8 9 file3: 9 10 11 12 13 file4: 13 14 15 16 17 file5: 17 18 19 20 这将使4个文件有5行,1个文件有4行 作为第一步,我尝试测试我编写的以下命令,以仅获取包含前5行

我有以下测试文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
我希望以一种方式将其分开,即每个文件都包含上一个文件的最后一行作为第一行。例如:

file 1:
1
2
3
4
5
file2: 
5
6
7
8
9
file3:
9
10
11
12
13
file4:
13
14
15
16
17
file5:
17
18
19
20
这将使4个文件有5行,1个文件有4行

作为第一步,我尝试测试我编写的以下命令,以仅获取包含前5行的第一个文件。我不明白为什么
if
语句中的
awk
命令不打印前5行,而是打印整个20行

d=$(wc test)
a=$(echo $d | cut -f1 -d " ")
lines=$(echo $a/5 | bc -l)
integer=$(echo $lines | cut -f1 -d ".")
for i in $(seq 1 $integer); do
start=$(echo $i*5 | bc -l)
var=$((var+=1))
echo start $start
echo $var
if [[ $var = 1 ]]; then
    awk 'NR<=$start' test
fi
done
d=$(wc测试)
a=$(回声$d |切-f1-d“”)
行=$(回声$a/5 | bc-l)
整数=$(回显$行|切-f1-d“。)
对于以美元表示的i(seq 1$整数);做
开始=$(回声$i*5 | bc-l)
var=$((var+=1))
echo start$start
echo$var
如果[[$var=1]];然后

awk'NR为什么不直接使用您的
POSIX
工具包中提供的
split
util呢。它有一个按行数拆分的选项,您可以按
5

split -l 5 input-file
人员拆分
页面

-l, --lines=NUMBER
       put NUMBER lines/records per output file

请注意,
-l
也是。

为什么不直接使用
POSIX
工具包中提供的
split
util呢。它有一个按行数拆分的选项,您可以按
5

split -l 5 input-file
人员拆分
页面

-l, --lines=NUMBER
       put NUMBER lines/records per output file
请注意,
-l
也是

如果您试图再次使用shell循环来操作文本,请确保先阅读,以了解至少一些使用awk的原因。要学习awk,请阅读Arnold Robbins的《有效的awk编程》,第四版

哦。并说明为什么您的awk命令
awk'NR

如果您试图再次使用shell循环来操作文本,请确保先阅读,以了解至少一些使用awk的原因。要学习awk,请阅读Arnold Robbins的《有效的awk编程》,第四版


哦。请解释为什么您的awk命令
awk'NR您可以通过删除不必要的
echo
cut
bc
来改进您的代码,并像这样做

#!/bin/bash
for i in $(seq $(wc -l < test) ); do
    (( i % 4 != 1 )) && continue
    tail +$i test | head -5 > "file$(( 1+i/4 ))"
done
#/bin/bash
对于以美元表示的i(seq$(wc-l“文件$((1+i/4))”
完成

但awk解决方案仍然要好得多。只读取一次文件,并根据随时可用的信息(如行号)采取措施是一种方法。在shell中,你必须数数行,没有办法绕过它
awk
将免费为您提供这些(以及许多其他东西)

您可以通过删除不必要的
echo
cut
bc
来改进代码,并按如下方式执行

#!/bin/bash
for i in $(seq $(wc -l < test) ); do
    (( i % 4 != 1 )) && continue
    tail +$i test | head -5 > "file$(( 1+i/4 ))"
done
#/bin/bash
对于以美元表示的i(seq$(wc-l“文件$((1+i/4))”
完成

但awk解决方案仍然要好得多。只读取一次文件,并根据随时可用的信息(如行号)采取措施是一种方法。在shell中,你必须数数行,没有办法绕过它
awk
将免费为您提供这些(以及许多其他东西)

使用
拆分

$ seq 20 | split -l 5
$ for fn in x*; do echo "$fn"; cat "$fn"; done
xaa
1
2
3
4
5
xab
6
7
8
9
10
xac
11
12
13
14
15
xad
16
17
18
19
20
或者,如果您有文件:

$ split -l test_file

使用
拆分

$ seq 20 | split -l 5
$ for fn in x*; do echo "$fn"; cat "$fn"; done
xaa
1
2
3
4
5
xab
6
7
8
9
10
xac
11
12
13
14
15
xad
16
17
18
19
20
或者,如果您有文件:

$ split -l test_file

你试过拆分吗?@123我添加了一个编辑,解释了这一点。@Ed Morton很抱歉搞混了。我最初的目标是sthg else(现在已在编辑版本中解释),但我只想问代码中的bug,所以我写了不同的问题。现在,我希望它更清晰。FYI获取文件中的行数,而不是
d=$(wc test);a=$(echo$d | cut-f1-d“”)
您只需执行
a=$(wc
。此外,学习始终引用shell变量对您来说非常重要。除非您需要双引号来达到特定目的,否则请使用单引号;除非您不需要双引号,否则请使用双引号。引号不是您需要时选择添加的内容,而是您不需要添加时选择不添加的内容。您是否尝试过拆分?@123我添加了一个编辑,解释了这一点。@Ed Morton很抱歉造成混淆。我最初的目标是sthg else(现在已在编辑版本中解释),但我只想问代码中的bug,所以我写了不同的问题。现在,我希望它更清晰。FYI获取文件中的行数,而不是
d=$(wc test);a=$(echo$d | cut-f1-d“”)
您只需执行
a=$(wc
。此外,学习始终引用shell变量对您来说非常重要。除非您需要双引号来达到特定目的,否则请使用单引号;除非您不需要双引号,否则请使用双引号。引号不是你需要时选择添加的东西,而是你不需要添加时选择不添加的东西;这是POSIX授权的实用程序。@Jens:是的!,不知道,我打了;)最初的问题基本上是“每4行打印文件中的5行”,其中包括行的重叠,这是拆分无法做到的;这是POSIX授权的实用程序。@Jens:是的!,不知道,我打了;)最初的问题基本上是“每4行打印文件中的5行”,其中包括行的重叠,这是拆分无法做到的。