如何在bash“for循环”中“变换”可变次数?

时间:2017-02-27 20:27:20

标签: linux bash tee

我明白我可以:

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

2 个答案:

答案 0 :(得分:4)

假设你的shell真的是bash(不是/bin/sh),你可以build an array(并使用C-style for loop,它与非标准外部命令seq不同,保证随处可见bash is):

#!/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 -- "$@" "file$i.txt"
  done
  exec tee -a -- "$@"
)

tee_between "file" ".txt" 1 10 <text.csv

注意:

  • set --修改当前进程(或者,在本例中为当前函数的参数列表),将其用作我们可以动态修改的数组。
  • tee_between() ( )而不是tee_between() { }意味着该函数在子shell中运行 - 一个完全独立的分叉过程。由于此选择,exec命令将仅使用tee的副本替换该子shell,而不是父进程。

答案 1 :(得分:3)

您不需要循环。可以为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)

请确保输出文件名前缀中没有任何空格,因为空格将被视为参数分隔符。