shell 创建100个包含“1”的文件,不使用for循环

ssgvzors  于 2022-11-16  发布在  Shell
关注(0)|答案(6)|浏览(187)

我试图制作一个脚本,创建100个名为log-01、log-02、log-03等的文件,每个文件都包含“1”,没有任何循环,但总是出现错误“不明确的重定向

#!bin/bash
echo "1">log-{01..100}

我试着在日志{01..100}前加上一个$,或者用引号括起来,但没有任何帮助。

jq6vz3qz

jq6vz3qz1#

输出只能重定向到单个文件,而不能重定向到多个文件。
如果需要多个输出文件,可以使用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)

这是少数几个必须 * 不 * 引用扩展的用例之一,因此可以在扩展后对其进行字段拆分。

n3ipq98p

n3ipq98p2#

你不能重定向到多个文件。你可以使用tee,正如已经指出的,或者你可以这样做:

printf '%s\n' {01..100} | xargs -P 100 I {} sh -c 'echo 1 > log-{}'

您可以使用-P来控制并行运行的进程数。
或者,如果您使用的平台支持它,例如大多数Linux发行版,您可以使用GNU parallel

printf '%s\n' {01..100} | parallel "echo 1 > log-{}"

或者你可以使用一个比shell更好的工具,它提供了更简单的方法来完成这个任务。例如,在awk中:

awk 'BEGIN{for(i=1;i<=100;i++){print "1" > "log-"sprintf("%.2d",i) }}'

在某些系统上打开太多文件可能会有问题,但如果使用gawk(GNU awk)就不会有问题。如果无法使用gawk,请尝试:

mawk 'BEGIN{for(i=1;i<=100;i++){file="log-"sprintf("%.2d",i); print "1" > file; close(file)}}'

awk方法的主要优势是速度。例如,如果创建1万个文件:

$ time ( printf '%s\n' {01..10000} | xargs -P 100 -I {} sh -c 'echo 1 > log-{}' )

real    0m4.375s
user    0m20.996s
sys     0m7.308s

$ time ( printf '%s\n' {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的速度也要快得多。

irtuqstp

irtuqstp3#

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}
ufj5ltwl

ufj5ltwl4#

检查以下内容:

seq 100 | xargs -i sh -c 'inputNo=$(printf %02d {}); echo "1" > log-$inputNo'
  • xargs* 是上帝的命令。
rsaldnfx

rsaldnfx5#

bash中的另一个解决方案:

. <(printf 'echo 1 >log-%s\n' {01..99} 100)

相关问题