分割文件:用“sed”替换“egrep”

分割文件:用“sed”替换“egrep”

我想分担我的$文件包含X将行分成两半,并检查有多少行包含“死的“在日志中。我从以下内容开始:

half=`expr $(egrep -c . $file) / 2`

sed -n 1,${half}p $file | 
    xargs echo $file $half $(egrep -c dead $I) > log_1
sed -n ${half},${egrep -c . $file}p | 
    xargs echo $file $half $(egrep -c dead $I) > log_2

第一个sed命令的输出正常,但是egrep在范围内替换时sed出现错误:

DeadOrAlive 5 2
-bash: ${half},${egrep -c . $file}p: bad substitution

有没有更有效的方法来分割文件bash

答案1

  1. 使用wcheadtail

    half=$(( $(wc -l "$file")/2 ))
    head -$half | egrep -c dead | xargs echo "$file" $half > log_1
    tail -$half | egrep -c dead | xargs echo "$file" $half > log_2
    
  2. 使用split

    split -a1 --numeric-suffixes=1 -n 'l/2' "$file" "$file"_
    echo "$file" "$file"_1 $(egrep -c dead "$file_1") > log_1
    echo "$file" "$file"_2 $(egrep -c dead "$file"_2) > log_2
    rm "$file"_[12]
    

答案2

这是一个 Awk 解决方案。

awk '/dead/ { a[++n] = NR }
    END { for (i=1; i<=n; i++) if (a[i] > NR/2) break
        print ARGV, int(NR/2), i-1 >"log_1";
        print ARGV, int(NR/2)+(int(NR/2)!=NR/2), n-i+1 >"log_2" }' file

我们将匹配的行号收集到数组中a。然后我们找出数组中有多少行号小于最中间的行;它们的计数被分配给第一个分区。(我们必须使用,因为当我们退出循环i-1时我们已经过了分区点。)break

一般来说,您要避免多次重新读取同一个文件,特别是当文件很大时;其次,尽量减少进程数。

不清楚您希望中间的输出字段包含什么。如果文件包含奇数行,则第一个“一半”将比第二个分区少一行。(这并不难改变,但您必须决定采用哪种方式。)

相关内容