我想添加一个像这样的分隔符“==============”和一个空白的新行
我尝试这样做,但失败并导致 CPU 使用率很高。我的意思是,当我运行脚本时,CPU 旋转速度很快且噪音很大
这需要用于大约 100000 个文本文件。
这是我使用的代码
#!/bin/bash
for F in *.txt ; do
type "$F"
echo .
echo ========
echo .
done >> Combined.txt;
请指教
答案1
我将简化您的命令如下:
#!/bin/bash
for file in *.txt; do
cat $file >> Combined.txt
printf '\n\n=========\n\n' >> Combined.txt
done
答案2
如果您要对数千个文件执行此操作,您可能希望避免每个文件运行多个命令。使用 GNU awk
:
printf '%s\0' ./*.txt | xargs -r0 gawk '
BEGINFILE {if (NR) print "\n==========\n"};1' > combined.out
如果您要将输出文件放在同一目录中,请不要.txt
为其提供扩展名,否则它将被选为输入文件并导致无限循环(可能首先是您的问题)。
或者使用内置的 shell,cat
例如ksh93
:
#! /bin/ksh93 -
firstpass=true
for file in *.txt; do
"$firstpass" || print '\n===========\n'
firstpass=false
command /opt/ast/bin/cat < "$file"
done > combined.out
循环中的所有这些命令都是内置的,因此运行它们不涉及分叉新进程或加载外部可执行文件,因此这将使性能可以接受。
答案3
使用FNR
和NR
在awk
#!/bin/bash
outfile="$( mktemp combined.txt.XXXXXX )"
echo "Output file: ${outfile}"
awk 'FNR==1 && NR>1 { printf("\n%s\n\n","========") } 1' *.txt > "${outfile}"
echo "Finished."
逐行描述:
outfile="$( mktemp combined.txt.XXXXXX )"
用于mktemp
创建具有唯一名称(例如 )的空新文件combined.txt.HDpgMn
。您可以使用更多X
字符来获得更长的随机后缀。将命令括在"$(
...中)"
以将新文件的名称存储在变量 中outfile
。
echo "Saving to file: ${outfile}"
打印输出文件的名称。 (脚本完成后,您可能希望重命名输出文件以删除 . 后面的随机字符串.txt
。)
awk 'FNR==1 && NR>1 { printf("\n%s\n\n","========") } 1' *.txt > "${outfile}"
打印...
- 一个空行,
- 一小行“=”字符,
- 和另一个空行
...在每个输入文件的开头,第一个输入文件除外。 FNR
计算输入文件的行数,并在每个文件的开头重置。 NR
计算行号并且不重置。
在该awk
语句中,1
右单引号之前的TRUE
每行计算结果为,并执行打印该行的默认操作。 (换句话说,awk '1'
工作原理类似于cat
。)
echo "Finished."
脚本完成后通知用户。 (并非绝对必要,因为无论如何您都会看到命令提示符,但这并没有什么坏处。)
答案4
为什么不简单地
printf "\n\n=====\n\n" > XTMP
cat $(printf "%s XTMP " *.txt) > combined.tmp
将分隔符放入临时文件中,并利用 的printf
功能为其找到的每个参数重复格式化字符串,因此cat
命令将如下所示
cat 1.txt XTMP 2.txt XTMP ... n.txt XTMP
不过,您可能会遇到系统限制(例如 LINE_MAX)...