gpt4 book ai didi

bash - 在终端中根据括号或括号(仅限顶级)拆分文本文件

转载 作者:行者123 更新时间:2023-11-29 09:31:04 25 4
gpt4 key购买 nike

我有几个要在 shell 脚本中处理的文本文件 (utf-8)。它们的格式并不完全相同,但如果我只能将它们分解成可食用的 block ,我就可以处理。这可以用 C 或 Python 编程,但我不喜欢。

EDIT: I wrote a solution in C; see my own answer. I think this may be the simplest approach after all. If you think I'm wrong please test your solution against the more complicated example input from my answer below.

-- jcxz100

为了清楚起见(并且能够更轻松地进行调试),我希望将 block 保存为子文件夹中的单独文本文件。

所有类型的输入文件包括:

  1. 垃圾线路
  2. 带有垃圾文本的行后跟开始方括号或圆括号 - 即 '[' '{' '<' 或 '(' - 可能后跟有效负载
  3. 有效载荷线
  4. 括号或圆括号嵌套在顶级对中的行;也被视为有效负载
  5. 带有结束括号或圆括号的有效负载行 - 即 ']' '}' '>' 或 ')' - 可能后跟某些内容(垃圾文本和/或新有效负载的开头)

我只想根据顶层括号/圆括号的匹配对来分解输入。这些对中的有效负载不得更改(包括换行符和空格)。顶级对之外的所有内容都应作为垃圾丢弃。

双引号内的任何垃圾或有效载荷都必须被视为原子(作为原始文本处理,因此其中的任何方括号或圆括号也应被视为文本)。

这是一个示例(仅使用 {} 对):

junk text
"atomic junk"

some junk text followed by a start bracket { here is the actual payload
more payload
"atomic payload"
nested start bracket { - all of this line is untouchable payload too
here is more payload
"yet more atomic payload; this one's got a smiley ;-)"
end of nested bracket pair } - all of this line is untouchable payload too
this is payload too
} trailing junk
intermittent junk
{
payload that goes in second output file }
end junk

...抱歉:某些输入文件确实如此困惑。

第一个输出文件应该是:

{ here is the actual payload
more payload
"atomic payload"
nested start bracket { - all of this line is untouchable payload too
here is more payload
"yet more atomic payload; this one's got a smiley ;-)"
end of nested bracket pair } - all of this line is untouchable payload too
this is payload too
}

...和第二个输出文件:

{
payload that goes in second output file }

注意:

  • 我还没有完全决定是否有必要在输出中保留这对开始/结束字符,或者它们本身是否应该作为垃圾丢弃。我认为保留它们的解决方案是更普遍的用途。

  • 在同一输入文件中可以混合使用多种类型的顶级括号/括号对。

  • 注意:输入文件中有 * 和 $ 字符,因此请避免混淆 bash ;-)

  • 相比简洁,我更喜欢可读性;但速度不会呈指数级增长。

锦上添花:

  • 文本中有反斜杠转义的双引号;最好他们应该被处理(我有一个 hack,但它并不漂亮)。

  • 脚本不应中断垃圾和/或负载中不匹配的括号/圆括号对(注意:在原子内部,它们必须被允许!)

更多的好东西:

  • 我还没有看到它,但可以推测某些输入可能使用单引号而不是双引号来表示原子内容……甚至是两者的混合。

  • 如果可以轻松修改脚本以解析具有相似结构但具有不同开始/结束字符或字符串的输入,那就太好了。

我看得出来这很啰嗦,但我认为如果我将它分解成更简单的问题,它不会提供可靠的解决方案。

主要问题是正确分割输入——其他一切都可以忽略或通过黑客“解决”,所以随意忽略nice-to-havesmore-far-out-nice-to-haves

最佳答案

给定:

$ cat file
junk text
"atomic junk"

some junk text followed by a start bracket { here is the actual payload
more payload
"atomic payload"
nested start bracket { - all of this line is untouchable payload too
here is more payload
"yet more atomic payload; this one's got a smiley ;-)"
end of nested bracket pair } - all of this line is untouchable payload too
this is payload too
} trailing junk
intermittent junk
{
payload that goes in second output file }
end junk

此 perl 文件会将您描述的 block 提取到文件 block_1block_2 等中:

#!/usr/bin/perl
use v5.10;
use warnings;
use strict;

use Text::Balanced qw(extract_multiple extract_bracketed);

my $txt;

while (<>){$txt.=$_;} # slurp the file

my @blocks = extract_multiple(
$txt,
[
# Extract {...}
sub { extract_bracketed($_[0], '{}') },
],
# Return all the fields
undef,
# Throw out anything which does not match
1
);
chdir "/tmp";
my $base="block_";
my $cnt=1;
for my $block (@blocks){ my $fn="$base$cnt";
say "writing $fn";
open (my $fh, '>', $fn) or die "Could not open file '$fn' $!";
print $fh "$block\n";
close $fh;
$cnt++;}

现在是文件:

$ cat block_1
{ here is the actual payload
more payload
"atomic payload"
nested start bracket { - all of this line is untouchable payload too
here is more payload
"yet more atomic payload; this one's got a smiley ;-)"
end of nested bracket pair } - all of this line is untouchable payload too
this is payload too
}

$ cat block_2
{
payload that goes in second output file }

使用 Text::Balanced 是可靠的并且可能是最佳解决方案。

可以使用单个 Perl 来完成这些 block regex :

$ perl -0777 -nlE 'while (/(\{(?:(?1)|[^{}]*+)++\})|[^{}\s]++/g) {if ($1) {$cnt++; say "block $cnt:== start:\n$1\n== end";}}' file
block 1:== start:
{ here is the actual payload
more payload
"atomic payload"
nested start bracket { - all of this line is untouchable payload too
here is more payload
"yet more atomic payload; this one's got a smiley ;-)"
end of nested bracket pair } - all of this line is untouchable payload too
this is payload too
}
== end
block 2:== start:
{
payload that goes in second output file }
== end

但这比使用像 Text::Balanced 这样的正确解析器要脆弱一些......

关于bash - 在终端中根据括号或括号(仅限顶级)拆分文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53835995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com