i有一系列文件,根据编号(file1.txt,file2.txt,file3.txt等)进行排序尴尬代码的输入。我可以将它们匹配为
awk ... file[1-$i].txt >> output
我想在该范围内排除文件,例如
file$v.txt
目标
我正在寻找
之类的东西awk ... file[1-!$v-$i].txt >> output
我从1- $ i匹配每个文件的地方,用$ v跳过文件。
我尝试了此处所述的复合模式匹配的各种输入,但是我无法让语法为我工作。
有人知道如何进行复合模式匹配吗?谢谢。
样品输入
应要求,这是我的文件:
file.1.dat
29.078306 0.00676358
29.223592 0.00309192
30.297306 0.0174575
30.478883 0.132458
30.503705 0.118951
30.512891 0.0705088
31.945900 0.00408244
32.321011 0.00258023
32.894037 0.00407912
32.916263 0.00330154
34.594139 0.00874524
34.849178 0.0195172
34.884655 0.00547378
34.967403 0.00308369
35.325397 0.00818193
file.2.dat
25.970535 0.0979715
26.913976 0.00593039
29.078306 0.0984052
29.223592 0.00271504
30.236632 0.013818
30.478883 0.0347606
30.503705 0.102369
30.512891 0.0409633
31.714064 0.0242958
31.902306 0.0510168
32.715764 0.0146584
34.952965 0.00484555
35.190790 0.0114201
35.360372 0.0033089
35.575199 0.00282864
38.184618 0.00551692
file.3.dat
31.591771 0.0126916
32.059389 0.0605918
32.299959 0.122618
32.890418 0.0058495
32.962536 0.00492958
33.646214 0.0705359
33.679538 0.120592
file.4.dat
25.636267 0.00398174
27.848542 0.00485739
28.269278 0.0174401
29.418886 0.00409613
31.313212 0.203932
31.945900 0.00259743
32.256620 0.00325607
32.299959 0.0325366
33.461363 0.0798633
33.646214 0.0516498
33.679538 0.12871
file.5.dat
29.767600 0.00777448
32.299959 0.00777995
34.849178 0.0305844
34.884655 0.0126815
34.930799 0.0546924
34.952965 0.0711241
尴尬代码
awk '
NR==FNR {
a[$1]=$2
next
}
($1 in a) {
a[$1]+=$2
}
END {
for(i in a)
print i,a[i]
}' file.4.dat file.[1-5].dat >| test.out
此代码执行以下操作:
- 匹配文件。
- 在找到$ 1中的匹配时,它将添加$ 2的文件。4。dat $ 2在匹配行中。
- test.out打印文件。
在这个问题中问了一个简单的示例,这是我从中获得尴尬代码的地方。
目标
我的目标是在我的输出中有以下行:
33.679538 0.249302
除其他正确匹配的线路外,但是这条线是我当前的测试,以查看它是否有效。现在,我有:
33.679538 0.378012
由于file.4.dat在awk代码中添加到自身,因为我不能在输入文件的第二个参数中排除它。
问题摘要
我的尴尬代码正在读取我的所有输入文件,我需要排除1个文件以获取正确的输出。
最终,我必须针对上面的awk代码中的其他4个文件分别输入我的5个文件中的每个文件。将来,文件数将是可变的,因此我不能仅在脚本中输入文件名。目前,如果我至少可以以不到10个文件解决此问题,那将是一个主要的帮助。
您可以在awk
中简单地执行此操作,通过识别您使用的第一个文件,并忽略使用nextfile
选项(需要GNU版本)的后续处理(需要GNU版本),该文件跳过处理文件以进行后续文件处理文件加工。通过此逻辑,您应该放置参考文件,例如 file.4.dat
在您的输入中作为文件列表中的第一个参数。
awk '
BEGIN{ ignoreFile = ARGV[1] }
NR==FNR {
a[$1]=$2
next
}
FILENAME == ignoreFile { nextfile }
($1 in a) {
a[$1]+=$2
}
END {
for(i in a)
print i,a[i]
}' file.4.dat file.[1-5].dat >| test.out
op想知道他们是否可以构建可以从外壳生成并使用的文件名的模式列表。可以完成,但是考虑到nextfile
可用的相对简单的选项,这看起来可能很复杂。
根据您的理解,您有n
文件,其中一个将用作参考文件。我更希望使用bash
Shell的ExtGlob功能包括除了参考之外的所有文件。例如我正在创建文件file1..10
用于解释此
touch file{1..10}
exclude=3
使用shopt
内置
shopt -s extglob
list=(!(file"$exclude"))
现在,使用declare -p list
打印数组,以查看仅包括参考文件的文件列表。现在,如下所示,使用awk
中的数组。数组扩展"${list[@]}"
导致您在上面生成的所有文件。
awk ... file"$exclude" "${list[@]}"
要跳过一个文件,您将ARGV[its position in the arg list]
设置为null。例如:
$ ls
file1 file2 file3
$ grep . file*
file1:x
file2:y
file3:z
$ awk 'BEGIN{ARGV[2]=""} {print FILENAME, $0}' file*
file1 x
file3 z
或者,如果您喜欢:
$ awk 'BEGIN{for (i in ARGV) if (ARGV[i]=="file2") ARGV[i]=""} {print FILENAME, $0}' file*
file1 x
file3 z
$ awk 'BEGIN{bad["file2"]; for (i in ARGV) if (ARGV[i] in bad) ARGV[i]=""} {print FILENAME, $0}' file*
file1 x
file3 z
$ awk '
BEGIN {
split("file2 file3",tmp); for (i in tmp) bad[tmp[i]]
for (i in ARGV) if (ARGV[i] in bad) ARGV[i]=""
}
{print FILENAME, $0}
' file*
file1 x
如果某人不想使用或在其系统中没有nextfile
,则跟随可以帮助您。
awk -v ignore="file.4.dat" '
FNR==1{
no_parse=""
}
FNR==NR {
a[$1]=$2
next
}
FILENAME == ignore{
no_parse=1
}
no_parse{
next
}
($1 in a) {
a[$1]+=$2
}
END {
for(i in a)
print i,a[i]
}' file.4.dat file.[1-5].dat >| test.out
创建了一个名为 ignore
的变量,我们可以提及input_file,我们需要忽略该变量,一旦input_file转弯来解析,我已经将名为 no_parse
的标志设置为true,在这种情况下,特定input_file的内容将被读取(因为next
用于跳过所有其他语句)
使用管道上的尴尬。您必须将最后一个文件作为参考(以下 -> 4)
awk ' $(NF+1)=FILENAME' file.[1-3].dat file.5.dat file.4.dat |
awk ' { a[$1]+=$2; $2=a[$1] } /file.4.dat/ && NF-- '
给定文件
$ awk ' $(NF+1)=FILENAME' file.[1-3].dat file.5.dat file.4.dat |
awk ' { a[$1]+=$2; $2=a[$1] } /file.4.dat/ && NF-- '
25.636267 0.00398174
27.848542 0.00485739
28.269278 0.0174401
29.418886 0.00409613
31.313212 0.203932
31.945900 0.00667987
32.256620 0.00325607
32.299959 0.162935
33.461363 0.0798633
33.646214 0.122186
33.679538 0.249302
$