Linux/Shell对大型文本文件进行切片
给定 文件1 文件2 我想做一个基本上做到这一点的方法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
$ 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
似乎都包含可以解释为正则表达式的字符。在这种情况下,GNUawk
解决方案应该可以使用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