如何通过分隔符将文件分成多个部分

如何通过分隔符将文件分成多个部分

我有一个文本文件如下:

aaaa 
bbbb
----  
cccc
----  
dddd

如何用作----分隔符并取出例如 dddd 或 cccc?我所说的“取出”是指运行一个命令并获取“dddd”,如果我的输入表明我想要整个文件的第三个字段。似乎awkorcut只在一行上操作,所以我想不出任何方法来使用这些命令来执行此操作。

答案1

您可以使用 sed 和 csplit 来执行此操作。

sed -i.bak 's/----/-/g' file && csplit --suppress-matched file '/-/' '{*}'
  • sed将在文件中将“----”替换为单个“-”(并创建备份以防万一)

  • csplit然后将根据单个“-”分割文件并输出多个文件[例如xx00,xx01等]

编辑:感谢@AdminBee 指出错字。从命令中删除了额外的“文件”。

答案2

#! /usr/bin/env bash

# split-textfile-by-first-line.sh

# split a text file by delimiter lines.
# the delimiter lines are included
# as first lines of the output files.

# removing the delimiter line
# would require patching
# the arguments for tail and head.

# (c) Milan Hauth, MIT License

set -eu

input_file="$1"
first_line="$2"

input_size=$(stat -c%s "$input_file")

start=
while read match; do
    # get the byte offset of match
    end=${match%%:*}
    if [ "$end" = "-1" ]; then
        # last match. set end to end of file
        end=$input_size
        if [ -z "$start" ]; then
            echo "error: first_line was not found in input_file"
            exit 1
        fi
    fi
    if [ -n "$start" ]; then
        output_file="$input_file".$start-to-$end
        cat "$input_file" |
            tail -c +$start |
            head -c $((end - start)) \
            >"$output_file"
        echo done "$output_file"
    fi
    start=$end
done < <(
    grep -bxF "$first_line" "$input_file"
    echo -1
)

答案3

使用 Raku(以前称为 Perl_6)

逐行读取:

~$ raku -ne 'BEGIN my @a; @a.push: $_ unless m/"----"/; END .say for @a[2];'  file
cccc

~$ raku -ne 'BEGIN my @a; @a.push: $_ unless m/"----"/; END .say for @a[3];'  file
dddd

一次读取所有文件:

~$ raku -e 'slurp.split(/ "\n" | "----" /, :skip-empty).[2].put;'  file
cccc

~$ raku -e 'slurp.split(/ "\n" | "----" /, :skip-empty).[3].put;'  file
dddd

Raku 是 Perl 编程语言家族中的一种编程语言。它具有内置的高级 Unicode 支持。在上面,您可以拉出您选择的零索引行,第三个所需行(零索引 == 2)或第四个所需行(零索引 == 3) )。

输入示例:

aaaa
bbbb
----
cccc
----
dddd

附录:使用 Raku 的lines例程(懒惰地阅读):

~$ raku -e '.[2].put if .chars for lines.map: *.split("----", :skip-empty);'  file
cccc

~$ raku -e '.[3].put if .chars for lines.map: *.split("----", :skip-empty);'  file
dddd

https://raku.org

相关内容