【问题标题】:create 100 files containing "1" without for loop创建 100 个包含 \"1\" 的文件而不使用 for 循环
【发布时间】:2022-10-17 05:46:56
【问题描述】:

我正在尝试制作一个脚本,该脚本将创建一百个名为 log-01、log-02、log-03 等的文件,每个文件中都包含“1”而没有任何循环,但它总是给出错误“模糊重定向

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

我尝试在 log-{01..100} 之前加上 $ 或将其放在引号中,但没有任何帮助。

【问题讨论】:

  • 你的输出应该有多少位数字?它应该是 log-1、log-01 还是 log-001? log-100 会发生什么,当一切只有 2 位数字时,它可以有 3 位数字吗?
  • fwiw,对于更大的序列(例如,10K、100K、1M、++),大括号扩展将需要更大的内存和 cpu 块,后续操作(例如,teexargs)甚至需要更多系统资源;所有这些都是在 OS/shell 级别执行大量重复性任务的缺点;对于较大的操作,可能值得看看是否有一些性能更高的非 shell 解决方案(例如,terdon 回答中的awk 解决方案)
  • stdout 重定向只能转到一个文件。毕竟,如果标准输出分配给一堆文件,程序应该怎么做???

标签: linux bash shell scripting


【解决方案1】:

输出只能重定向到单个文件,不能重定向到多个文件。

如果你想要多个输出文件,你可以使用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)

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

【讨论】:

  • 为什么它创建“log-1”、“log-2”等而不是“log-01”、“log-02”?
  • @Dair 没有。它通过 log-100 创建 log-001。我刚刚再次测试了它(bash 5.2)。你可以试试{001-100},也许有帮助
  • bash 4.0 中添加了对前导零的支持。
  • 如果你想要log-001,你需要使用log-{001..100}而不是log-{01..100}。 OP 使用的是{01..100} 所以 knittl,我认为这就是他们想要的。
  • 但是log-{01..100} 扩展为log-001 ...log-100,与log-{001..100} 完全相同,这是(?)不受欢迎的。您需要 log-{{01..99},100} 将其保持为 2 位数,直到出现 log-100 的特殊情况(如果这是 OP 的意图)。应该是log-{00..99} 吗?
【解决方案2】:

您不能重定向到多个文件。正如已经指出的那样,您可以使用tee,或者您可以执行以下操作:

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

您可以使用-P 来控制并行运行的进程数。

或者,如果您使用的是支持它的平台,例如大多数 Linux 发行版,您可以使用 GNU parallel

printf '%s
' {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 方法的主要优点是速度。例如,如果创建 10,000 个文件:

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

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


$ time ( printf '%s
' {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

正如您在上面看到的,awk 即使在并行运行具有 100 个作业的其他工具时也明显更快。外壳是减缓.

【讨论】:

  • 使用mawk2 - 我在创建114,688 files 时对它进行了基准测试,mawk2 出现在9609 files/sec7682 files/secgawk -byte-mode
【解决方案3】:

您的命令 echo "1"&gt;log-{01..100} 由 bash 扩展为等效行:

echo "1">log-001 log-002 log-003 log-004 log-005 log-006

并且该结构对于您的目的来说很奇怪/模棱两可/错误。

一个好的解决方案是使用@knittl 建议的tee 命令。 tee 获取文件列表并将标准输入接收到的输入写入其中:

echo "1" | tee log-{1..100}

【讨论】:

  • 可能要提一下,如果ulimit (-n) 太低,您可以在足够多的文件上点击“打开的文件太多”错误,例如:ulimit -n == 3200 ...echo "1" | tee log-{1..10000} =&gt; tee: log-3198: Too many open files
【解决方案4】:

检查这个:

seq 100 | xargs -i sh -c 'inputNo=$(printf %02d {}); echo "1" > log-$inputNo'

xargs是上帝的命令。

【讨论】:

  • 更容易只是seq 100 | xargs -i sh -c 'echo "1" &gt; log-$(printf %02d {})'
【解决方案5】:

bash 中的另一个解决方案:

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

【讨论】:

    【解决方案6】:
    gawk -p- -be 'BEGIN { 
    
    '"$( jot -w 'print ("1")>(__=sprintf("log-%%05.f.txt",
                                          %d)); close(__);' 100 )"'
    
    }'
    
    # gawk profile, created Mon Oct 10 14:23:07 2022
    
    # BEGIN rule(s)
    
    BEGIN {
     1      print("1") > (__ = sprintf("log-%05.f.txt", 1))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 2))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 3))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 4))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 5))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 6))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 7))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 8))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 9))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 10))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 11))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 12))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 13))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 14))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 15))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 16))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 17))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 18))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 19))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 20))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 21))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 22))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 23))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 24))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 25))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 26))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 27))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 28))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 29))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 30))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 31))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 32))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 33))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 34))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 35))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 36))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 37))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 38))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 39))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 40))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 41))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 42))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 43))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 44))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 45))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 46))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 47))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 48))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 49))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 50))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 51))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 52))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 53))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 54))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 55))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 56))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 57))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 58))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 59))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 60))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 61))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 62))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 63))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 64))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 65))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 66))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 67))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 68))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 69))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 70))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 71))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 72))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 73))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 74))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 75))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 76))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 77))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 78))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 79))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 80))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 81))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 82))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 83))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 84))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 85))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 86))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 87))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 88))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 89))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 90))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 91))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 92))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 93))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 94))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 95))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 96))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 97))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 98))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 99))
     1      close(__)
     1      print("1") > (__ = sprintf("log-%05.f.txt", 100))
     1      close(__)
    }
    
    head *      
    
    ==> log-00001.txt <==
    1
    
    ==> log-00002.txt <==
    1
    
    ==> log-00003.txt <==
    1
    
    ==> log-00004.txt <==
    1
    
    ==> log-00005.txt <==
    1
    ...
    

    【讨论】:

      猜你喜欢
      • 2023-02-01
      • 2019-11-25
      • 2014-05-09
      • 1970-01-01
      • 2018-07-30
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多