Как "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, а не родительским процессом.