创建 100 个包含 "1" 的文件,不带 for 循环



我试图制作一个脚本,该脚本将创建一百个名为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)
gawk -p- -be 'BEGIN { 
'"$( jot -w 'print ("1")>(__=sprintf("log-%%05.f.txt",
%d)); close(__);' 100 )"'
}'
D_15

最新更新