[英]Is there a way to make permutations for file names in a for loop in linux bash?
这个想法是您有 3 个文本文件,我们将其命名为A B C ,其中您只有一个带有字符串的唯一列(本示例中的内容无关紧要)。 您想要的是在这三个之间建立一个连接 function,因此您将连接A - B另一个连接B - C和最后一个连接 A - Z0D61F8370CAD1D412F570B84D143 ,如果它是一个排列。
让我们做一个图形示例。 个人代码将是
join -1 1 -2 1 A.txt B.txt > AB.txt
其他 2 以此类推
想象A有
100
101
102
104
乙有
101
103
104
105
C有
100
103
104
105
所以A - B比较( AB.txt )将是:
101
104
A - C比较( AC.txt ):
100
104
B - C比较( BC.txt ):
103
105
您将拥有三个 output 文件,以比较AB.txt 、 AC.txt和BC.txt 命名
解决方案可能如下所示:
#!/usr/bin/env bash
# Read positional parameters into array
list=("$@")
# Loop over all but the last element
for ((i = 0; i < ${#list[@]} - 1; ++i)); do
# Loop over the elements starting with the first after the one i points to
for ((j = i + 1; j < ${#list[@]}; ++j)); do
# Run the join command and redirect to constructed filename
join "${list[i]}" "${list[j]}" > "${list[i]%.txt}${list[j]%.txt}".txt
done
done
请注意, -1 1 -2 1
是join
的默认行为,可以跳过。
必须使用文件名作为参数调用脚本:
./script A.txt B.txt C.txt
我会将文件放在一个数组中,并使用如下索引:
files=(a.txt b.txt c.txt) # or files=(*.txt)
for ((i=0; i<${#files[@]}; i++)); do
f1=${files[i]} f2=${files[i+1]:-$files}
join -1 1 -2 1 "$f1" "$f2" > "${f1%.txt}${f2%.txt}.txt"
done
使用echo join
进行调试(并引用>
),这就是将要执行的:
join -1 1 -2 1 a.txt b.txt > ab.txt
join -1 1 -2 1 b.txt c.txt > bc.txt
join -1 1 -2 1 c.txt a.txt > ca.txt
或者对于六个文件:
join -1 1 -2 1 a.txt b.txt > ab.txt
join -1 1 -2 1 b.txt c.txt > bc.txt
join -1 1 -2 1 c.txt d.txt > cd.txt
join -1 1 -2 1 d.txt e.txt > de.txt
join -1 1 -2 1 e.txt f.txt > ef.txt
join -1 1 -2 1 f.txt a.txt > fa.txt
LC_ALL=C; files(*.txt)
LC_ALL=C; files(*.txt)
将使用当前目录中的所有.txt
文件,按名称排序,这可能是相关的。
GNU awk 中的一个:
$ gawk '{
a[ARGIND][$0] # hash all files to arrays
}
END { # after hashing
for(i in a) # form pairs
for(j in a)
if(i<j) { # avoid self and duplicate comparisons
f=ARGV[i] ARGV[j] ".txt" # form output filename
print ARGV[i],ARGV[j] > f # output pair info
for(k in a[i])
if(k in a[j])
print k > f # output matching records
}
}' a b c
Output,例如:
$ cat ab.txt
a b
101
104
所有文件都在开头的 memory 中进行哈希处理,因此如果文件很大,您可能会用完 memory。
一个 function 除了在其 arguments 中生成两个可能的组合之外什么都不做:
#!/bin/bash
combpairs() {
local a b
until [ $# -lt 2 ]; do
a="$1"
for b in "${@:2}"; do
echo "$a - $b"
done
shift
done
}
combpairs A B C D E
A - B
A - C
A - D
A - E
B - C
B - D
B - E
C - D
C - E
D - E
另一种变化
declare -A seen
for a in {A,B,C}; do
for b in {A,B,C}; do
[[ $a == $b || -v seen[$a$b] || -v seen[$b$a] ]] && continue
seen[$a$b]=1
comm -12 "$a.txt" "$b.txt" > "$a$b.txt"
done
done
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.