简体   繁体   English

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

[英]How do I “tee” variable number of times in a bash “for loop”?

I understand I can: 我明白我可以:

ssh archive_server -l user -n "cat text.csv"|tee -a text1.csv|tee -a text2.csv|tee....|tee -a text10.csv

Is there a way to do it aa loop? 有没有办法做一个循环?

for i in `seq 1 10`; do
  echo $i
  tee ???
done

Assuming your shell is really bash (not /bin/sh ), you can build an array (and use a C-style for loop , which unlike the nonstandard external command seq , is guaranteed to be available everywhere bash is): 假设你的shell真的是bash(而不是/bin/sh ),你可以构建一个数组 (并使用一个C风格for循环 ,这与非标准的外部命令seq ,保证在bash所有地方都可用):

#!/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

If you need compatibility with /bin/sh , it gets a little bit more verbose: 如果你需要兼容/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

Note: 注意:

  • set -- modifies the current process's (or, in this case, the current function's) argument list, using that as an array we can dynamically modify. set --修改当前进程(或者,在本例中是当前函数的)参数列表,使用它作为我们可以动态修改的数组。
  • tee_between() ( ) instead of tee_between() { } means that the function runs in a subshell -- a completely separate forked-off process. tee_between() ( )而不是tee_between() { }意味着该函数在子shell中运行 - 一个完全独立的分叉过程。 In consequence of this choice, the exec command will replace only that subshell with a copy of tee , and not the parent process. 由于这个选择, exec命令将仅使用tee的副本替换该子shell,而不是父进程。

You don't need a loop. 你不需要循环。 tee can be given multiple filename arguments, so just give all the output files at once: tee可以被赋予多个文件名参数,所以只需一次提供所有输出文件:

cat text.csv | tee -a text{1..10}.csv

If the number of files is dynamic, you can use a loop in $() to insert the filenames into the command line: 如果文件数是动态的,您可以使用$()的循环将文件名插入命令行:

cat text.csv | tee -a $(
    for i in $(seq 1 $filecount); do
        echo text$i;
    done)

Just make sure that you don't have any whitespace in the output filename prefix, as the spaces will be treated as argument delimiters. 只需确保输出文件名前缀中没有任何空格,因为空格将被视为参数分隔符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM