Скрипт оболочки, используйте awk для поиска по диагонали
Я ищу способ получить все диагональные комбинации из этого блока букв:
a b c d e f
h i j k l m
o p q r s t
v w x y z a
c d e f g h
j k l m n o
у меня есть это: awk '{++f; print $(f + 0)}' file.txt
но это только у меня (если я могу увеличить, f + 0, как-то с 1, 6 раз):
a i q y g o
b j r z h
c k s a
d l t
e m
f
и мне нужна другая половина, чтобы.. как это (не должно быть в этом порядке:
a i q y g o
h p x f n
b j r z h
o w e m
c k s a
v d l
d l t
c k
e m
j
f
3 ответа
Решение
perl -lane'
push @r, [@F];
END {
for my $n (0 .. $#r) {
my (@x,@y);
for (0 .. $#r) {
push @x, $r[$n+$_][$_];
push @y, $r[$_][$n+$_];
}
print "@x";
print "@y" if $n;
}
}
' file
выход
a i q y g o
h p x f n
b j r z h
o w e m
c k s a
v d l
d l t
c k
e m
j
f
Вы можете использовать GNU datamash:
$ datamash -t' ' transpose < file
a h o v c j
b i p w d k
c j q x e l
d k r y f m
e l s z g n
f m t a h o
Это работа для массива.
#!/usr/bin/awk -f
# Print diagonals from a square of text.
# This script has no error checking.
# Written by PM 2Ring 2014.10.13
{
for(i=1; i<=NF; i++)
a[NR,i] = $i
}
END{
for(i=1; i<=NR; i++)
{
for(j=1; i+j-1<=NR; j++)
printf "%s ", a[i+j-1, j]
print ""
if (i == 1)
continue
for(j=1; i+j-1<=NR; j++)
printf "%s ", a[j, i+j-1]
print ""
}
}
Вот версия приведенного выше кода, которая хранит каждое диагональное слово в массиве.
#!/usr/bin/awk -f
# Print diagonals from a square of text.
# This script has no error checking.
# Written by PM 2Ring 2014.10.13
{
for(i=1; i<=NF; i++)
a[NR,i] = $i
}
END{
k = 1
for(i=1; i<=NR; i++)
{
word = ""
for(j=1; i+j-1<=NR; j++)
word = word a[i+j-1, j]
words[k++] = word
if (i == 1)
continue
word = ""
for(j=1; i+j-1<=NR; j++)
word = word a[j, i+j-1]
words[k++] = word
}
numwords = k
for (k=1; k<numwords; k++)
print words[k]
}
выход
aiqygo
hpxfn
bjrzh
owem
cksa
vdl
dlt
ck
em
j
f
Печать ортогональных диагоналей, например, "flrxdj", оставлена в качестве упражнения для читателя.
...
Вот функция, которая печатает все подслова в данном слове.
#!/usr/bin/awk -f
# Print subwords of a given word
# Written by PM 2Ring 2014.10.13
function print_subwords(s, i, j, len)
{
len = length(s)
for (i=1; i<=len; i++)
{
print "Length:", i
for (j=1; i+j-1 <= len; j++)
print substr(s, j, i)
}
}
BEGIN{
print_subwords("ABCD")
}
выход
Length: 1
A
B
C
D
Length: 2
AB
BC
CD
Length: 3
ABC
BCD
Length: 4
ABCD