我有一个很大的二进制文件。我想从中提取某些字符串并将它们复制到一个新的文本文件中。
例如,在:
D-wM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM-FM MM-[o@^B^@^@^@^@^@E7cacscKLrrok9bwC3Z64NTnZM-^G
我想取数字“7”(在@^@^@e
之后),以及它之后的每个字符都停在Z
(忽略M-^G
)。
不幸的是,我对grep、sed等的知识并没有扩展到这个层次。有人能提出一个可行的方法来达到这个目的吗?
cat-v filename grep[7][A-Z,A-Z]
将显示所有带有“7”后跟字母的字符串,但这并不多。
谢谢你。
我想检查一个字符串的结尾,如果它以m-
结尾,则grep后面的另一个字符串(中间有垃圾)。如果字符串没有以m-
结尾,那么我不希望它被复制(更别提任何其他字符串了)。
所以我想要的是:
grep-a-po“7[[:alnum:]]+(?=m-)”file_name
如果结尾是m-
则grep-a-po“5x[[:alnum:]]+(?=\^)”file_name
复制以5x
开头、以^
结尾的字符串。
在本例中:
D-wM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM-FM MM-[o@^B^@^@^@^@^@E7cacscKLrrok9bwC3Z64NTnZM-^GwM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM5x8w09qewqlkcklwnlkewflewfiewjfoewnflwenfwlkfwelk^89038432nowefe
其结果将是:
7cacscKLrrok9bwC3Z64NTnZ
5x8w09qewqlkcklwnlkewflewfiewjfoewnflwenfwlkfwelk
但是,如果结尾不是m-
(更准确地说,如果结尾是^s
),则不要尝试第二个grep并且完全不记录任何内容。
D-wM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM-FM MM-[o@^B^@^@^@^@^@E7cacscKLrrok9bwC3Z64NTnZ^SGwM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM5x8w09qewqlkcklwnlkewflewfiewjfoewnflwenfwlkfwelk^89038432nowefe
grep是正确的工具吗?Grep一个文件,如果Grep命令中的条件是'yes',则发出另一个Grep命令,但如果条件是'no',则不执行任何操作。
再次感谢。
我注意到一个附加修改。
如何将5x
更改为5x
或6x
?
D-wM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM-FM MM-[o@^B^@^@^@^@^@E7cacscKLrrok9bwC3Z64NTnZM-^GwM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM5x8w09qewqlkcklwnlkewflewfiewjfoewnflwenfwlkfwelk^89038432nowefe
D-wM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM-FM MM-[o@^B^@^@^@^@^@E7AAAAAscKLrrok9bwC3Z64NTnZM-^GwM-^?^@^@^@^@^@^@^@^Y^@^@^@^@^@^@^@M-lM-FM-MM-[o@^B^@M-lM6x8w09qewqlkcklwnlkewflewfiewjfoewnflwenfwlkfwelk^89038432nowefe
在本例中,期望的结果是:
7cacscKLrrok9bwC3Z64NTnZ
5x8w09qewqlkcklwnlkewflewfiewjfoewnflwenfwlkfwelk
7AAAAAscKLrrok9bwC3Z64NTnZ
6x8w09qewqlkcklwnlkewflewfiewjfoewnflwenfwlkfwelk
3月09日更新:
我需要二进制文件中的两个字符串。
第一个字符串将始终以1
开头。
第一个字符串将以字母或数字结尾。下一个字母将始终是小写k
。我不想要这个k
字符。
第二个字符串的结尾将采用以下两种形式之一:a)以空格结尾,然后以小写显示第一个字符串的前三个字符,后跟)
b)以^K
结尾,然后以小写显示第一个字符串的前三个字符。
例如:
<代码>1PPPSX9YPAR8RVS75TJYWZQ3EO8PGWBCKB4M4ZT7YG042KIDYUE82E893HY ppp)
应该是:
1pppsx9ypar8rvs75tjywzq3eo8pgwbc
和b4m4zt7yg042kidyue82e893hy
-删除k
和空格,然后删除ppp
。
例如:
1ZZZSX9YPKAR8RVS75TJYWZQ3EO8PGWBC
和A4M4ZT7YG042KIDYUE82E893HY
-删除第二个K
和^KZZZ
。
在第二个示例中,我们看到第一个k
是第一个字符串的一部分。分解第一个和第二个字符串的是A
之前的K
。
希望有一位超级grep专家能帮上忙!多谢!
如果您的grep
支持-p
选项,请尝试:
grep -a -Po "7[[:alnum:]]+(?=M-)" file
-a
选项强制grep
将输入作为文本文件读取。-p
选项启用与Perl兼容的正则表达式。-o
选项告诉grep
只打印匹配的子字符串。(?=m-)
是一个零宽度的前瞻断言(在Perl中引入),但不包括在结果中。或者,您也可以使用sed
:
sed 's/M-/\n/g' file | sed -n 's/.*\(7[[:alnum:]]\+\).*/\1/p'
sed
命令通过用换行符替换子字符串m-
来将输入文件拆分为多行。它有两个好处:中断行以允许使用sed
进行多个匹配,并从输入中排除不必要的部分m-
。sed
命令从输入中提取所需的模式。sed 's/M-/\'$'\n''/g' file | sed -n 's/.*\(7[[:alnum:]]\+\).*/\1/p'
[UPDATE]
(该需求已由OP更新,以下是根据该需求提供的解决方案。)
让我假设以7
开头、以M-
结尾的字符串后面总是跟一个以5x
开头、以^
(ascii插入符号)结尾且中间有垃圾的字符串(不多也不少于一个)。
那么请尝试以下操作:
grep -aPo "7[[:alnum:]]+M-.*?5x[[:alnum:]]+\^" file | grep -aPo "7[[:alnum:]]+(?=M-)|5x[[:alnum:]]+(?=\^)"
.*?
匹配除换行符以外的任何(ascii或二进制)字符。尾随的?
启用最短匹配
,这避免了由于regex的贪婪
性质而导致的溢出。正则表达式用于匹配介于两者之间的垃圾。
表示逻辑或
。然后提取两个所需序列。grep
解决方案的一个潜在问题是,grep
是面向行的命令,不能在匹配的字符串中包含换行符。如果在between
中包含了换行符(我不确定可能性),则上述解决方案将失败。作为一种解决办法,perl
将提供对二进制数据的灵活操作。
perl -0777 -ne '
while (/(7[[:alnum:]]+)M-.*?(5x[[:alnum:]]+)\^/sg) {
printf("%s\n%s\n", $1, $2);
}
' file
grep
的regex基本相同,因为grep
的-p
选项表示与Perl兼容。$1
和$2
中的多个模式,因此只要一个正则表达式就足够了。perl
命令的-0777
选项告诉perl
一次发出所有数据的声音。s
选项使点与换行符匹配。G
选项启用全局
(多重)匹配。[UPDATE2]
为了使正则表达式匹配5x
或6x
,请将5x
替换为(56)x
。
即:
grep -aPo "7[[:alnum:]]+M-.*?(5|6)x[[:alnum:]]+\^" file | grep -aPo "7[[:alnum:]]+(?=M-)|(5|6)x[[:alnum:]]+(?=\^)"
如前所述,管道表示
或
。或
运算符在计算中的优先级最低,因此在本例中需要将它们用括号括起来。
如果可能出现5或6以外的任何其他数字,则使用[[:digit:]]
更安全,它与0和9之间的任何一个数字匹配:
grep -aPo "7[[:alnum:]]+M-.*?[[:digit:]]x[[:alnum:]]+\^" file | grep -aPo "7[[:alnum:]]+(?=M-)|[[:digit:]]x[[:alnum:]]+(?=\^)"
[UPDATE3]
(3月9日回答OP的要求)
让我从perl
代码开始,它的regex相对更容易解释。
perl -0777 -ne 'while (/(1(.{3}).+)k([AB].*)[\013 ]\2/g){print "$1 $3\n"}' file
输出:
1pppsx9YPar8Rvs75tJYWZq3eo8Pgwbc B4m4zT7Yg042KIDYUE82e893hY
1zzzsx9YPkr8Rvs75tJYWZq3eo8Pgwbc A2m4zT7Yg042KIDYUE82e893hY
(1(.{3}).+)k([AB].*)[\013 ]\2
( start of the 1st capture group referred by $1 later
1 literal "1"
( start of the 2nd capture group referred by \2 later
.{3} a sequence of the identical three characters such as ppp or zzz
) end of the 2nd capture group
.+ followed by any characters with "greedy" match which may include the 1st "k"
) end of the 1st capture group
k literal "k"
( start of the 3rd capture group referred by $3 later
[AB].* the character "A" or "B" followed by any characters
) end of the 3rd capture group
[\013 ] followed by ^K or a whitespace
\2 followed by the capture group 2 previously assigned
grep -Po "(1(.{3}).+)(?=k([AB].*)[\013 ]\2)" file
grep -Po "(1(.{3}).+)k\K([AB].*)(?=[\013 ]\2)" file
1pppsx9YPar8Rvs75tJYWZq3eo8Pgwbc
1zzzsx9YPkr8Rvs75tJYWZq3eo8Pgwbc
B4m4zT7Yg042KIDYUE82e893hY
A2m4zT7Yg042KIDYUE82e893hY
请注意,输出的顺序与原始文件中出现的顺序不同。
另一个选择是引入ripgrep
或rg
,这是grep
的快速多功能版本。您可能需要使用sudo apt install ripgrep
或其他包处理工具安装ripgrep。ripgrep
的一个优点是它支持-r
(replace)选项,您可以在该选项中使用反向引用:
rg -N -Po "(1(.{3}).+)k([AB].*)[\013 ]\2" -r '$1 $3' file
-r'$1$3'
选项打印第一个和第三个捕获组,结果与perl
相同。
我有非常大的二进制文件,其中包含y传感器的x个int16数据点,以及包含一些基本信息的头文件。二进制文件被写为每个采样时间的y值,最多x个采样,然后是另一组读数,依此类推。如果我想要所有的数据,我使用的是numpy。fromfile(),它工作得又快又好。然而,如果我只需要传感器数据的子集或特定传感器,我目前有一个可怕的double for循环,使用的是这要花很长时间。在python中有没有其他更
我创建了一个方法,根据文件中的行号从文件中读取特定行。它对大多数文件都很好,但当我试图读取一个包含大量非常长的行的文件时,它需要很长时间,特别是当它在文件中的位置越来越深时。我还做了一些调试,似乎也占用了大量内存,但我不确定这是否可以改进。我知道还有一些其他的问题集中在如何从文件中读取某些行,但这个问题主要集中在性能方面。 如何优化此方法以使其比光速更快?
问题内容: 我想读Python中的大文件时,了解在这个方法内存使用率的差异。 第1版,发现这里的计算器: 版本2,我用在此之前,我发现上面的代码: 该文件在两个版本部分阅读。而目前的一块可以被处理。在第二个例子,是在每个周期中获得新的内容,所以我认为这将做的工作,以 不 完整的文件加载到内存..? 但我真的不明白是什么呢,我敢肯定我得到的东西错在这里。任何人都可以解释给我吗? 还有别的,我感到困惑
我有一个字符串。我想从中提取。为此,我正在努力 但是在输出上我得到了。 我怎样才能走出地狱世界。 谢谢
根据https://docs.python.org/3.4/library/venv.html#module-venv所说的“每个虚拟环境都有自己的Python二进制文件(允许创建具有各种Python版本的环境)”,那么我如何使用具有Python 2.7二进制文件的venv模块来创建虚拟环境呢?
下面是一个示例字符串: