Как "tee" переменное количество раз в bash для цикла?
Я понимаю, что могу:
ssh archive_server -l user -n "cat text.csv"|tee -a text1.csv|tee -a text2.csv|tee....|tee -a text10.csv
Есть ли способ сделать это цикл?
for i in `seq 1 10`; do
echo $i
tee ???
done
Ответы
Ответ 1
Вам не нужен цикл. tee
может быть задано несколько аргументов имени файла, поэтому просто сразу укажите все выходные файлы:
cat text.csv | tee -a text{1..10}.csv
Если количество файлов является динамическим, вы можете использовать цикл в $()
, чтобы вставить имена файлов в командную строку:
cat text.csv | tee -a $(
for i in $(seq 1 $filecount); do
echo text$i;
done)
Просто убедитесь, что у вас нет пробелов в префиксе выходных файлов, поскольку пробелы будут рассматриваться как разделители аргументов.
Ответ 2
Предполагая, что ваша оболочка действительно bash (не /bin/sh
), вы можете построить массив (и использовать цикл C
#!/bin/bash
filenames=( )
for ((i=1; i<=10; i++)); do # note that the "10" here can be a variable name
filenames+=( "file$i.txt" )
done
tee -a -- "${filenames[@]}" <text.csv
Если вам нужна совместимость с /bin/sh
, он становится немного более подробным:
#!/bin/sh
tee_between() (
prefix=$1; suffix=$2; start=$3; end=$4
set --
i=$(( $start - 1 )); while [ $(( ( i += 1 ) <= end )) -ne 0 ]; do
set -- "[email protected]" "file$i.txt"
done
exec tee -a -- "[email protected]"
)
tee_between "file" ".txt" 1 10 <text.csv
Примечание:
-
set --
изменяет список аргументов текущего процесса (или, в данном случае, текущей функции), используя это как массив, который мы можем динамически изменять.
-
tee_between() ( )
вместо tee_between() { }
означает, что функция работает в подоболочке - совершенно отдельный процесс раздвоения. Вследствие этого выбора команда exec
заменит только эту подоболочку копией tee
, а не родительским процессом.