我有以下内容:
-值文件,values.txt
-目录结构:./dataset/label/author/files.txt
-数以万计的文件.txt的
-名为target.txt的文件,其中包含每个files.txt的位置
targets.txt示例
./dataset/tallperson/Jabba/awesome.txt
./dataset/fatperson/Detox/toxic.txt
我有一个名为values.txt的文件,其中包含成千上万行值。这些值是诸如“ aef”,“; i”,“ jfk”等之类的。3个字符的随机行。
我还有成千上万个文件,每个文件也包含成百上千行。每行还包含3个字符的随机行。
使用每个files.txt的值创建了values.txt。因此,任何file.txt文件中都没有value.txt中不包含的值。 values.txt不包含重复值。
示例:
./ dataset / weirdperson / Crooked / file1.txt
LOL
hel
lo
how
are
you
on
thi
s f
ine
day
./ dataset / awesomeperson / Mild / file2.txt
I a
m v
ery
goo
d.
Tha
nks
LOL
values.txt
are
you
on
thi
s f
ine
day
goo
d.
Tha
hel
lo
how
I a
m v
ery
nks
LOL
以上仅是示例数据。每个文件将包含数百行。而且values.txt将包含成千上万的行。
我的目标是制作一个文件,其中每一行都是一个文件。每行将包含N个值,其中每个值对应于values.txt中的行。每个值都将用逗号分隔。每个值的计算方法很简单,即每个文件包含values.txt中每一行的值的次数。
结果应如下所示。第1行是file1.txt,第2行是file2.txt。
Result.txt
1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,
0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,
现在。最后一件事是,在获得此结果之后,我想添加一个标签。该标签等效于文件中的第N个父目录。对于此示例,假设第二个父目录。因此,标签将为“高人”或“矮人”。结果,新的Results.txt文件将如下所示。
Results.txt
1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,weirdperson
0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,awesomeperson
我想要一种方法来完成所有这些工作,但是当我使用超大规模数据集时,我需要它要快速。
这是我当前的代码,但是太慢了。瓶颈是第2行。
脚本。每个文件位于“ ./dataset/label/author/file.java”
1 while IFS= read file_name; do
2 cat values.txt | xargs -d '\n' -I {} grep -Fc -- "{}" "$file_name" | xargs printf "%d," >> Results.txt;
3 label=$(echo "$file_name" | cut -d '/' -f 3);
4 printf "$label\n" >> Results.txt;
5 done < targets.txt
-----------< em>-
要复制此问题。请执行以下操作:
mkdir -p dataset/{label1,label2}
touch file1.txt; chmod 777 file1.txt
touch file2.txt; chmod 777 file2.txt
echo "Enter anything here" > file1.txt
echo "Enter something here too" > file2.txt
mv file1.txt ./dataset/label1
mv file2.txt ./dataset/label2
find ./dataset/ -type f -name "*.txt" | while IFS= read file_name; do cat $file_name | sed -e "s/.\{3\}/&\n/g" | sort -u > $modified-file_name; done
find ./dataset/ -type f -name "modified-*.txt" | xargs -d '\n' -I {} echo {} >> targets.txt
xargs cat < targets.txt | sort -u > values.txt
使用上面的UNCHANGED,您应该获得一个values.txt,其中包含类似下面的内容。如果出于某些原因,任何行中的字符少于或少于3个,请删除该行。
any
e
Ent
er
eth
he
her
ing
ng
re
som
thi
too
您应该获得一个target.txt文件
./dataset/label2/modified-file2.txt
./dataset/label1/modified-file1.txt
从这里开始。目的是检查targets.txt中的每个文件,并计算该文件在values.txt中包含多少个值。并将带有标签的结果输出到Results.txt
以下脚本可用于该示例,但我需要它可以更快地用于大规模操作。
while IFS= read file_name; do
cat values.txt | xargs -d '\n' -I {} grep -Fc -- "{}" $file_name | xargs printf "%d," >> Results.txt;
label=$(echo "$file_name" | cut -d '/' -f 3);
printf "$label\n" >> Results.txt;
done < targets.txt
这是另一个例子
示例2:
./ dataset / weirdperson / Crooked / file1.txt
LOL
LOL
HAHA
./ dataset / awesomeperson / Mild / file2.txt
LOL
LOL
LOL
values.txt
LOL
HAHA
Result.txt
2,1,weirdperson
3,0,awesomeperson
答案 0 :(得分:0)
尝试一下:
<targets.txt xargs -n1 -P4 bash -c "
awk 'NR==FNR{a[\$0];next} {if (\$0 in a) {printf \"1,\"} else {printf \"0,\"}}' \"\$1\" values.txt |
sed $'s\x01$\x01'\"\$(<<<\"\$1\" cut -d/ -f3)\"'\n'$'\x01'
" --
通过-P4
,您可以并行化targets.txt
中的作业。简短的awk脚本对行进行标记并打印0和1,后跟逗号。然后使用sed
将文件夹路径的第3部分附加到该行的末尾。 sed
行看起来很奇怪,因为我使用了不可打印的字符$'\x01'
作为s
命令的分隔符。
经过测试:
mkdir -p ./dataset/weirdperson/Crooked
cat <<EOF >./dataset/weirdperson/Crooked/file1.txt
LOL
hel
lo
how
are
you
on
thi
s f
ine
day
EOF
mkdir -p ./dataset/awesomeperson/Mild/
cat <<EOF >./dataset/awesomeperson/Mild/file2.txt
I a
m v
ery
goo
d.
Tha
nks
LOL
EOF
cat <<EOF >values.txt
are
you
on
thi
s f
ine
day
goo
d.
Tha
hel
lo
how
I a
m v
ery
nks
LOL
EOF
cat <<EOF >targets.txt
./dataset/weirdperson/Crooked/file1.txt
./dataset/awesomeperson/Mild/file2.txt
EOF
measure_start() {
declare -g ttic_start
echo "==> Test $* <=="
ttic_start=$(date +%s.%N)
}
measure_end() {
local end
end=$(date +%s.%N)
local start
start="$ttic_start"
ttic_runtime=$(python -c "print(${end} - ${start})")
echo "Runtime: $ttic_runtime"
echo
}
measure_start original
while IFS= read file_name; do
cat values.txt | xargs -d '\n' -I {} grep -Fc -- "{}" $file_name | xargs printf "%d,"
label=$(echo "$file_name" | cut -d '/' -f 3);
printf "$label\n"
done < targets.txt
measure_end
measure_start first try with bash
nl -w1 values.txt | sort -k2.2 > values_sorted.txt
< targets.txt xargs -n1 -P0 bash -c "
sort -t$'\t' \"\$1\" |
join -t$'\t' -12 -21 -eEMPTY -a1 -o1.1,2.1 values_sorted.txt - |
sort -s -n -k1.1 |
sed 's/.*\tEMPTY/0/;t;s/.*/1/' |
tr '\n' ',' |
sed $'s\x01$\x01'\"\$(<<<\"\$1\" cut -d/ -f3)\"'\n'$'\x01'
" --
measure_end
measure_start second try with awk
<targets.txt xargs -n1 -P0 bash -c "
awk 'NR==FNR{a[\$0];next} {if (\$0 in a) {printf \"1,\"} else {printf \"0,\"}}' \"\$1\" values.txt |
sed $'s\x01$\x01'\"\$(<<<\"\$1\" cut -d/ -f3)\"'\n'$'\x01'
" --
measure_end
输出:
==> Test original <==
1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,weirdperson
0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,awesomeperson
Runtime: 0.133769512177
==> Test first try with bash <==
0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,awesomeperson
1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,weirdperson
Runtime: 0.0322473049164
==> Test second try with awk <==
0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,awesomeperson
1,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,weirdperson
Runtime: 0.0180222988129