Я знаю, что вы сказали bash
, но это идеально подходит для такого языка, как python 3.3+
import sys
from contextlib import ExitStack
from itertools import product
with ExitStack() as stack:
files = [stack.enter_context(open(f)) for f in sys.argv[1:]]
for x in product(*files):
x = [y.rstrip('\n') for y in x]
print(*x)
. код выше в файле с именем combo.py
и назовите его таким образом python combo.py file_1 file_2 file_3
Он генерирует
1_a 2_a 3_a
1_a 2_a 3_b
1_a 2_a 3_c
1_a 2_b 3_a
1_a 2_b 3_b
1_a 2_b 3_c
1_b 2_a 3_a
1_b 2_a 3_b
1_b 2_a 3_c
1_b 2_b 3_a
1_b 2_b 3_b
1_b 2_b 3_c
1_c 2_a 3_a
1_c 2_a 3_b
1_c 2_a 3_c
1_c 2_b 3_a
1_c 2_b 3_b
1_c 2_b 3_c
Вы дали нам очень расплывчатое описание того, что вы пытаетесь сделать, поэтому этот ответ, вероятно, будет таким же расплывчатым, но:
head
и tail
предназначены для этой цели.
Если вы хотите игнорировать все, кроме первых десяти результатов, используйте:
head -n 10
И чтобы игнорировать все, кроме последних десяти результатов, используйте:
tail -n 10
Примечание. :Это работает, только если ваши результаты разделены символами новой строки.
Используя zsh
, шаблон
*(.[11,-1])
будет соответствовать всем именам обычных файлов (, а не именам каталогов и т. д. )в текущем каталоге, сортируя их по имени (порядок сортировки по умолчанию ), и будет возвращать все, кроме первых десяти из эти имена.
Тестирование:
$ touch file-{01..20}
$ ls
file-01 file-03 file-05 file-07 file-09 file-11 file-13 file-15 file-17 file-19
file-02 file-04 file-06 file-08 file-10 file-12 file-14 file-16 file-18 file-20
$ printf '%s\n' *(.[11,-1])
file-11
file-12
file-13
file-14
file-15
file-16
file-17
file-18
file-19
file-20
Вы хотите удалить эти файлы:
$ rm *(.[11,-1])
$ ls
file-01 file-02 file-03 file-04 file-05 file-06 file-07 file-08 file-09 file-10
Обратите внимание, что для этого требуется оболочка zsh
и что другая оболочка, такая как bash
, не будет понимать особый тип используемого шаблона подстановки.
Из какой-нибудь другой оболочки можно использовать
zsh -c 'rm *(.[11,-1])'
В bash
вы можете сделать что-то вроде
names=( * )
printf '%s\n' "${names[@]:10}"
, чтобы перечислить имена файлов, которые вы, возможно, захотите удалить, но нет гарантии, что перечисленные имена являются именами обычных файлов, вполне могут быть и имена каталогов. Так что вы можете зациклить:
for name in *; do
if [ -f "$name" ]; then
files+=( "$name" )
fi
done
printf '%s\n' "${files[@]:10}"
Это также подберет имена символических ссылок, которые указывают на обычные файлы.
Чтобы удалить их, используйте rm "${files[@]:10}"
.
Как и в случае со всеми операциями по удалению данных, вы должны протестировать любое решение на копиях реальных данных, прежде чем запускать их в реальном времени.