我试图制作一个脚本,该脚本将创建一百个名为log-01、log-02、log-03等的文件,其中包含";1〃;它们中的每一个都没有任何循环,但它总是给出一个错误";模糊重定向
#!bin/bash
echo "1">log-{01..100}
我试着在日志前加一个$-{01.100}或把它放在引号里,但没有任何帮助。
输出只能重定向到单个文件,而不能重定向到多个文件。
如果你想要多个输出文件,你可以使用tee
:
#!/bin/bash
echo '1' | tee log-{01..99} log-100
这将创建名为log-01、log-02、…、log-98、log-99和log-100的文件。
请注意,以上内容仅适用于从4.0版本开始的bash。如果您的bash较旧,并且不支持使用前导零格式化大括号展开,则可以使用带有命令替换的普通旧shell:
#!/bin/sh
echo '1' | tee $(printf 'log-%02d ' $(seq 100))
# or formatting with GNU sed directly:
echo '1' | tee $(seq -f 'log-%02g' 100)
这是为数不多的必须引用扩展而不是的用例之一,因此可以在扩展后对其进行字段拆分。
您不能重定向到多个文件。正如已经指出的,您可以使用tee
,也可以执行类似的操作:
printf '%sn' {01..100} | xargs -P 100 I {} sh -c 'echo 1 > log-{}'
您可以使用-P
来控制并行运行的进程数量。
或者,如果你使用的是支持它的平台,比如大多数Linux发行版,你可以使用GNUparallel
:
printf '%sn' {01..100} | parallel "echo 1 > log-{}"
或者,您可以使用比shell更好的工具,它提供了更简单的方法。例如,在awk
:中
awk 'BEGIN{for(i=1;i<=100;i++){print "1" > "log-"sprintf("%.2d",i) }}'
在某些系统上,您可能会遇到打开文件过多的问题,但如果您使用gawk
(GNUawk
(执行此操作,则不会出现问题。如果您不能使用gawk
,请尝试:
mawk 'BEGIN{for(i=1;i<=100;i++){file="log-"sprintf("%.2d",i); print "1" > file; close(file)}}'
awk方法的主要优点是速度。例如,如果创建10000个文件:
$ time ( printf '%sn' {01..10000} | xargs -P 100 -I {} sh -c 'echo 1 > log-{}' )
real 0m4.375s
user 0m20.996s
sys 0m7.308s
$ time ( printf '%sn' {01..10000} | parallel -j 100 "echo 1 > log-{}")
real 0m12.640s
user 0m21.504s
sys 0m12.414s
$ time gawk 'BEGIN{for(i=1;i<=10000;i++){print "1" > "log-"sprintf("%.2d",i) }}'
real 0m0.954s
user 0m0.803s
sys 0m0.148s
$ time gawk 'BEGIN{for(i=1;i<=10000;i++){f="log-"sprintf("%.2d",i); print "1" > f; close(f) }}'
real 0m0.133s
user 0m0.020s
sys 0m0.109s
正如您在上面看到的,即使在并行运行具有100个作业的其他工具时,awk
也会明显更快。外壳缓慢。
bash将命令echo "1">log-{01..100}
扩展到等效行:
echo "1">log-001 log-002 log-003 log-004 log-005 log-006
这种结构对于你的目的来说是奇怪的/模棱两可的/错误的。
一个好的解决方案是使用@knittl建议的tee
命令。tee
获取文件列表,并在其中写入标准输入接收到的输入:
echo "1" | tee log-{1..100}
检查此项:
seq 100 | xargs -i sh -c 'inputNo=$(printf %02d {}); echo "1" > log-$inputNo'
xargs是上帝的命令。
bash
中的另一个解决方案:
. <(printf 'echo 1 >log-%sn' {01..99} 100)
D_15gawk -p- -be 'BEGIN { '"$( jot -w 'print ("1")>(__=sprintf("log-%%05.f.txt", %d)); close(__);' 100 )"' }'