我的机器上有三个 Markdown 文件:
$ ls | grep md
bar.md
baz.md
foo.md
每个文件都有给定的内容:
$ cat *md
i am bar
i am baz
i am foo
举个例子,我想“循环遍历与模式匹配的所有文件*.md
并打印模式:file_name: file_contents
”。
我最喜欢使用 ruby。但我想练习一下我的bash for 循环并也发展我的awk技能。
Ruby 对我来说是最简单的:
#!/usr/bin/env ruby
# iterate over all markdown files in current directory
Dir.glob('*.md').each do |some_file|
puts "#{some_file}: #{File.read(some_file)}"
end
输出:
$ ./iterate_over_files.rb
bar.md: i am bar
baz.md: i am baz
foo.md: i am foo
并按照链接bash 资源我创建了以下 for 循环:
#!/usr/bin/env bash
# iterate over all markdown files in current directory
for some_file in *.md
do
echo $some_file: `cat $some_file`
done
给出相同的输出:
$ diff <(./iterate_over_files.sh) <(./iterate_over_files.rb) # no difference
我通过观看演示得知布赖恩·科纳汉并从审查他的幻灯片这是使用 awk 的好机会,因为它遵循以下模式:
for each file
for each input line
for each pattern
if the pattern matches input line
do the action
- 如何使用 awk 来利用此模式并迭代所有 Markdown 文件并打印格式化结果?
答案1
怎么样,处理每个文件并使用 FILENAME 变量输出文件名。
$ awk '{print FILENAME":",$0}' *.md
bar.md: i am bar
baz.md: i am baz
foo.md: i am foo
$
或者这个,有点难看,但只需将 $0 设置为文件名,后跟文件内容。默认操作awk
是打印 $0,所以这就是为什么它不需要print
.
$ awk '$0=FILENAME": "$0' *.md
bar.md: i am bar
baz.md: i am baz
foo.md: i am foo
$
另一种方法。不使用 FILENAME,而是使用 ARGV 参数数组。
$ awk '$0=ARGV[++z]": "$0' *.md
bar.md: i am bar
baz.md: i am baz
foo.md: i am foo
$
答案2
根据bash
手册,您应该使用$(< FILE)
而不是$(cat FILE)
.但根本不需要使用命令替换:
for some_file in *.md
do
echo -n "$some_file: "
cat $some_file
done
由于您已经知道进程替换,您还可以执行以下操作:
for some_file in *.md
do
cat <(echo -n "$some_file: ") $some_file
done