bash如何根据字段内容从分隔字符串中提取字段

bash如何根据字段内容从分隔字符串中提取字段,bash,Bash,问题-我有一组字符串,基本上如下所示: |AAAAAA|BBBBBB|CCCCCCC|...|XXXXXXXXX|...|ZZZZZZZZZ| “…”表示省略的字段。 请注意,管道之间的字段(“|”)可以以任何顺序出现,但并非所有字段都必须出现。我的任务是找到“XXXXXXX”字段并从字符串中提取它;我可以用正则表达式指定该字段,并用grep/awk/等找到它,但一旦从文件中提取了这一行,我就不知道如何只提取管道之间的文本 我的搜索结果是将行分割成单独的字段,然后提取第N个字段,然而,我不知道

问题-我有一组字符串,基本上如下所示:

|AAAAAA|BBBBBB|CCCCCCC|...|XXXXXXXXX|...|ZZZZZZZZZ|
“…”表示省略的字段。 请注意,管道之间的字段(“|”)可以以任何顺序出现,但并非所有字段都必须出现。我的任务是找到“XXXXXXX”字段并从字符串中提取它;我可以用正则表达式指定该字段,并用grep/awk/等找到它,但一旦从文件中提取了这一行,我就不知道如何只提取管道之间的文本

我的搜索结果是将行分割成单独的字段,然后提取第N个字段,然而,我不知道N是什么,这就是诀窍

我曾想过用分隔符拆分字符串,用换行符替换分隔符,将这些行用grep表示字段,但这涉及到运行另一个程序,这将通过近TB的数据在生产服务器上运行,因此我希望尽量减少程序调用。我不能将文件复制到另一台机器上,也没有Python、Perl等语言的优势,我只能在SunOS上使用“标准”UNIX命令。我想我正在受到惩罚

谢谢

当然,这只有在
xxxxxxxx
是正则表达式时才有意义

如果使用以下方法,这应该非常快:

$ grep '|XXXXXXXXX|' somefile | sed -e ...
当然,这只有在
xxxxxxxx
是正则表达式时才有意义

如果使用以下方法,这应该非常快:

$ grep '|XXXXXXXXX|' somefile | sed -e ...
一种粗俗的方式-

sed 's/^.*|\(<whatever your regex is>\)|.*$/\1/'
sed的/^.*\(\)\.*$/\1/'
但这对于生产服务器来说可能太慢了,因为它可能涉及相当多的regex回溯。

一种黑客方式-

sed 's/^.*|\(<whatever your regex is>\)|.*$/\1/'
sed的/^.*\(\)\.*$/\1/'

但这对于生产服务器来说可能太慢了,因为它可能涉及大量的正则表达式回溯。

例如,让我们提取与
MyField
匹配的字段:

使用sed
-p
选项需要GNU grep。

例如,让我们提取与
MyField
匹配的字段:

使用sed
-p
选项需要GNU grep。

“我可以用正则表达式指定该字段”如果您展示了这样一个正则表达式的示例,这将非常有用。还可以显示具有预期输出的示例输入数据。
grep-o XXXXXXX文件
<代码>grep XXXXXXX文件| tr\|'\n'| grep XXXXXXX?“我可以用正则表达式指定该字段”如果您演示这样一个正则表达式的示例,这将非常有用。还可以显示具有预期输出的示例输入数据。
grep-o XXXXXXX文件
grepxxxxxxx文件| tr\|'\n'| grepxxxxxxx
?感谢您的回复,我认为这很好,但奇怪的是,无论我对regex使用什么。。。"" ... 将输出整个文件,包括空行和全部。我甚至剪切粘贴了你的sed命令,得到了文件中的每一行。这种情况发生在SunOS和MAC OS X上。感谢您的回复,我认为这是很好的,但奇怪的是,无论我在正则表达式中使用什么。。。"" ... 将输出整个文件,包括空行和全部。我甚至剪切粘贴了你的sed命令,得到了文件中的每一行。这发生在SunOS和MAC OS X上。感谢您的回复。不幸的是,所有的例子都不适用于SunOS,这是一个永无止境的主题。由于这台机器正在生产,我们可能看不到任何现代的东西。以此为借口,我将在我的Mac上运行这个,sed示例运行得非常好。基本的答案是用与正则表达式匹配的部分替换整行,因此我给自己一个大大的“Duh!”@user3481644对此表示抱歉。在SunOS上,默认的
awk
确实有一些bug。请尝试
nawk
或更好的
/usr/xpg4/bin/awk
/usr/xpg6/bin/awk
。感谢您的回复。不幸的是,所有的例子都不适用于SunOS,这是一个永无止境的主题。由于这台机器正在生产,我们可能看不到任何现代的东西。以此为借口,我将在我的Mac上运行这个,sed示例运行得非常好。基本的答案是用与正则表达式匹配的部分替换整行,因此我给自己一个大大的“Duh!”@user3481644对此表示抱歉。在SunOS上,默认的
awk
确实有一些bug。试试
nawk
或者更好的
/usr/xpg4/bin/awk
或者
/usr/xpg6/bin/awk
$ awk -F\| -v re="MyField" '{for (i=1;i<=NF;i++) if ($i~re) print $i}' <<<"$s"
12MyField34
$ grep -Po '(?<=\|)[^|]*MyField[^|]*' <<<"$s"
12MyField34