Linux/Shell对大型文本文件进行切片

Linux/Shell对大型文本文件进行切片,linux,bash,awk,grep,Linux,Bash,Awk,Grep,给定 文件1 文件2 我想做一个基本上做到这一点的方法 $ command uniquename2 apple $ command uniquename1 hello $ command uniquename3 hello 因此,给定file1中的uniquename,它将使用file2中的键来获取它的链接。如果找不到uniquename,什么也不做 我的尝试 $ grep -i 'uniquename1' | (not sure how to slice the line with rege

给定

文件1

文件2

我想做一个基本上做到这一点的方法

$ command uniquename2
apple
$ command uniquename1
hello
$ command uniquename3
hello
因此,给定file1中的uniquename,它将使用file2中的键来获取它的链接。如果找不到uniquename,什么也不做

我的尝试

$ grep -i 'uniquename1' | (not sure how to slice the line with regex "*:*:*") | grep $thisline file2

sed
使这相对容易。例如:

$ sed -n "/$(sed -n '/uniquename2/s/.*[:]//p' file1)/s/.*[:]//p" file2
apple

您只需使用命令substitution
$(sed-n'/uniquename3/s/*[:]//p'f1)
uniquename
中获取
uniquekey
,修剪行的前导部分,然后使用
sed-n/$(command)/s/*[:]//p对结果执行相同的操作,以获得所需字符串
在外部使用双引号以允许命令替换展开

所使用的基本
sed
命令的形式是正常的替换
s/find/replace
,其前导模式与总计匹配

sed '/match/s/find/replace/`
-n
抑制图案空间的正常打印,最后的
p
使其在匹配和替换成功时打印

如果
uniquename
uniquekey
包含正则表达式字符

鉴于您对实际文件返回错误的评论,实际文件中的每个
uniquename
uniquekey
似乎都包含可以解释为正则表达式的字符。在这种情况下,GNU
awk
解决方案应该可以使用
FILENAME
变量根据
分隔的字段从每个文件中提取所需信息:“
,例如

$ awk -F: -v name=uniquename2 '
    FILENAME == "file1" { $1 == name && key = $NF } 
    FILENAME == "file2" { if ($1 == key) print $NF }
' file1 file2
apple

如果你有问题,请告诉我。此外,如果您可以发布一些
file1
file2
的实际示例(例如每行10行),这将有所帮助。

剪切工具是为此类数据设计的:

#!/bin/bash
KEY=$(grep -i -e "^$1:" file1.txt | cut -d ':' -f 4)
grep -e "^$KEY" file2.txt | cut -d ':' -f 2

这里是一个只扫描两个文件一次的
awk
脚本。与嵌套的
grep
解决方案不同,执行
uniqueId*(uniqueId-1)
文件扫描

script.awk

BEGIN {FS=":"} # field separator is :
FNR == NR && $1 == keyArg {id = $NF} # find the id in first file
FNR == NR {next} # continue scanning first file
$1 == id {print $2} # find the id in second file and print its 2nd field value
执行:

 awk -v keyArg="uniquename2" -f script.awk file1 file2 

正确答案是:

$ awk -v tgt='uniquename2' -F':' 'NR==FNR{map[$1]=$2; next} $1==tgt{print map[$NF]}' file2 file1
apple

或者差不多(请参见下面的注释)。

当我尝试使用更大的文件时,我会得到这样一个结果:“sed:-e expression#1,char 15:unknown command:`m'”是否有DOS行以其中一个文件结尾?(命令中没有
'm'
)@aki还有,
somethinguseless:somethinguseless
实际上是什么?如果存在有意义的字符作为
regex
,那么我可以看出这会导致问题。不管怎样,它们可以是任何东西。那么,有没有一种方法可以得到一行的结尾:/?好的,给我一点时间考虑一下如何删除任何特殊的含义。我不确定,如果是这样的话,任何解释正则表达式的方法都会起作用。这几乎可以起作用,但问题是,如果唯一名称的开头相似,那么它就会抓住它。例如:“aaabc123:…”和“abc123”。如果我想抓取abc123,它将抓取aaabc123,而不是headi修改了第一个grep命令,以匹配从行首到第一个冒号的顺序。我修改了第二个grep,使其在键的末尾使用冒号,并从行的开头到键的结尾进行匹配。最近我想到:somethinguseless:somethinguseless:可能包含“:”,这给了我一些错误的输出。但是,它确实适用于大多数没有“:”的人。uniquename/uniquekey不包含“:”。如果没有更好的数据描述,我们只是猜测解决方案。
FNR==NR&$1==keyArg{id=$NF;next}
应该是
FNR==NR{if($1==keyArg)id=$NF;next}
因此
next
适用于file1的所有行,不仅仅是$1与keyArg匹配的1行。
BEGIN {FS=":"} # field separator is :
FNR == NR && $1 == keyArg {id = $NF} # find the id in first file
FNR == NR {next} # continue scanning first file
$1 == id {print $2} # find the id in second file and print its 2nd field value
 awk -v keyArg="uniquename2" -f script.awk file1 file2 
$ awk -v tgt='uniquename2' -F':' 'NR==FNR{map[$1]=$2; next} $1==tgt{print map[$NF]}' file2 file1
apple