gpt4 book ai didi

bash - 从 shell 脚本的行数中提取公共(public)部分文本

转载 作者:行者123 更新时间:2023-11-29 09:27:45 26 4
gpt4 key购买 nike

我想从给定行数中提取文本的公共(public)部分。输入:

/dir1/dir2/dir3/dir4/a/file1/dir
/dir1/dir2/dir3/dir4/b/file2
/dir1/dir2/dir3/dir4/c/file3/dir
/dir1/dir2/dir3/dir4/a/file4
/dir1/dir2/dir3/dir4/e/file5

预期输出是 dir1 到 dir4 的公共(public)部分。示例预期输出:

/dir1/dir2/dir3/dir4/

到目前为止我尝试过的代码:通过管道将输入输入到 awk 命令,然后如下所示

awk '{for(i=1;i<=NF;i++)if($i | sort | uniq -c -ne 1)var = i; break;}

但我无法让它正常工作..我知道我可能在逻辑上或我对 awk 命令的理解上出错了。有人可以帮忙吗?

最佳答案

最长公共(public)前缀问题的 Perl 解决方案

perl -le '@a=<>; $p=$a[0]; for (@a){ chop $p while ! /^\Q$p/ }; print $p' file

构造数组@a来自 <>输入文件的
$p是最长的前缀,初始化为数组中的第一个元素$a[0]
遍历数组 @a 的元素
而前缀 $p不匹配 ! //开始^当前元素的 chop关闭最后一个字符。
\Q告诉正则表达式引擎忽略任何潜在的元字符
最后,打印前缀 $p

输出:

/dir1/dir2/dir3/dir4/

使用 -n 的替代实现隐式构造循环:

perl -lne 'BEGIN{$p = <>}; chop $p while ! /^\Q$p/; END{print $p}' file


使用 substr() 的替代实现而不是 /regex/

perl -lne 'BEGIN{$p=<>} chop $p while $p ne substr($_,0,length($p)); END{print $p}' file

-n遍历文件的每一行
$_包含当前行内容


使用 awk 的替代实现:

awk 'NR==1{p=$0} {while(p != substr($0,1,length(p))){p=substr(p,1,length(p)-1)}} END{print p}' file


使用 Python 的替代实现:

#!/usr/bin/python3
import sys
fp = open(sys.argv[1], 'r')
p = fp.readline()
for line in fp:
while (line.find(p) != 0):
p = p[:-1]
print(p)

使用 C 的替代实现:

#include <stdio.h>
#include <string.h>
#define MAXLINE 1000
int main (int argc, char* argv[]) {
FILE *fp = fopen(argv[1], "r");
char p[MAXLINE];
char line[MAXLINE];
fgets(line, MAXLINE, fp);
strcpy(p, line);
while (fgets(line, MAXLINE, fp)) {
while ( strstr(line, p) != line && strlen(p) > 0 ) {
p[strlen(p)-1] = '\0';
}
}
printf("%s\n", p);
}

为了好玩,我使用 20MB 输入文件和 10 次运行对各种解决方案进行了基准测试
我的 perl 解决方案列为 a、b、c
在 perl 5.20 和 5.22 上测试
还列出了@karakfa 和我的 awk 解决方案,使用 awk 3.1.5 和 gawk 4.1.0
@balabhi 的 shell 解决方案也列出了
TL;DR:perl substr() 解决方案 (c) 是脚本语言中最快的,但您使用哪种解决方案并不重要

                 Rate awk_karakfa gawk_karakfa perl_5.20_b perl_5.22_b perl_5.22_a perl_5.20_a   awk gawk python_3.4.2 shell_balabhi perl_5.22_c perl_5.20_c    c
awk_karakfa 0.618/s -- -12% -46% -51% -56% -58% -58% -80% -81% -82% -85% -86% -98%
gawk_karakfa 0.701/s 13% -- -38% -44% -50% -52% -52% -77% -79% -80% -83% -84% -97%
perl_5.20_b 1.14/s 84% 62% -- -10% -19% -22% -22% -63% -65% -67% -72% -74% -96%
perl_5.22_b 1.26/s 104% 80% 11% -- -11% -13% -13% -59% -61% -63% -69% -71% -95%
perl_5.22_a 1.41/s 128% 101% 24% 12% -- -3% -3% -55% -57% -59% -65% -68% -95%
perl_5.20_a 1.46/s 135% 108% 28% 15% 3% -- -0% -53% -55% -58% -64% -67% -95%
awk 1.46/s 136% 108% 28% 15% 3% 0% -- -53% -55% -58% -64% -67% -95%
gawk 3.11/s 402% 343% 173% 146% 120% 113% 113% -- -5% -10% -23% -30% -89%
python_3.4.2 3.27/s 428% 366% 187% 159% 131% 125% 124% 5% -- -5% -19% -26% -88%
shell_balabhi 3.45/s 458% 392% 203% 173% 144% 137% 137% 11% 6% -- -15% -22% -88%
perl_5.22_c 4.05/s 555% 477% 256% 221% 187% 178% 178% 30% 24% 17% -- -8% -85%
perl_5.20_c 4.41/s 612% 528% 287% 249% 212% 203% 202% 42% 35% 28% 9% -- -84%
c 27.8/s 4392% 3861% 2342% 2100% 1867% 1808% 1806% 794% 750% 706% 586% 531% --

关于bash - 从 shell 脚本的行数中提取公共(public)部分文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33527278/

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