我有多個檔案(其中將近 1000 個)由空格分隔,我需要僅使用第二列來計算每個檔案之間的連接函式的排列。重要的是不能重復比較,這就是排列的原因。
例如,一個包含 3 個檔案A.txt B.txt和C.txt的小例子
一般的想法是得到AB比較,AC和BC。既不是BA 也不是 CA 也不是 CB
101 代碼將是
join -1 2 -2 2 A.txt B.txt | cut -d ' ' -f1 > AB.txt
join -1 2 -2 2 A.txt C.txt | cut -d ' ' -f1 > AC.txt
join -1 2 -2 2 B.txt C.txt | cut -d ' ' -f1 > BC.txt
有沒有辦法為數千個檔案做到這一點?我嘗試使用 for 回圈,但我的腦子被烤焦了,現在我正在嘗試使用 while 回圈。但我最好先了解一下方向。
uj5u.com熱心網友回復:
由于迭代次數非常大,性能成為一個問題。這是 Matty 答案的優化版本,使用陣列將迭代次數除以 2(半百萬而不是一百萬)并避免測驗:
declare -a files=( *.txt )
declare -i len=${#files[@]}
declare -i lenm1=$(( len - 1 ))
for (( i = 0; i < lenm1; i )); do
a="${files[i]}"
ab="${a%.txt}"
for (( j = i 1; j < len; j )); do
b="${files[j]}"
join -1 2 -2 2 "$a" "$b" | cut -d ' ' -f1 > "$ab$b"
done
done
但是考慮到 bash 并不是為這種具有 50 萬次迭代的密集任務而設計的。可能有更好(更有效)的方法來完成你想要的。
uj5u.com熱心網友回復:
看起來您所追求的可以通過兩個嵌套的 for 回圈和字典比較來完成以保持字母順序?
# prints pairs of filenames
for f in dir/*; do
for g in dir/*; do
if [[ "$f" < "$g" ]]; then # ensure alphabetical order
echo $f $g
fi
done
done
uj5u.com熱心網友回復:
這就是您不想為此使用 bash 的原因:
首先創建1000個檔案
seq 1000 | xargs touch
現在,與 bash 不同的對
time {
files=(*)
len=${#files[@]}
for ((i=0; i<len-1; i )); do
a=${files[i]}
for ((j=i 1; j<len; j )); do
b=${files[j]}
echo "$a $b"
done
done >/dev/null
}
real 0m5.091s
user 0m4.818s
sys 0m0.262s
與,例如,在 perl 中相同:
time {
perl -e '
opendir my $dh, ".";
my @files = sort grep {$_ != "." && $_ != ".."} readdir $dh;
closedir $dh;
for (my $i = 0; $i < @files - 1; $i ) {
my $a = $files[$i];
for (my $j = $i 1; $j < @files; $j ) {
my $b = $files[$j];
print "$a $b\n";
}
}
' > /dev/null
}
real 0m0.131s
user 0m0.120s
sys 0m0.006s
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/378753.html
