本质上,我想做的是非破坏性地对目录中的每个文本文件运行 awk - 并将结果具有相同的文件名在不同的目录中
换句话说,我想使用 awk 操作目录中的每个文件,结果是一个目录,其中包含在具有相同文件名的文件中运行 awk 的结果。
假设我位于目录 foo 中,其中包含文件 f1.txt、f2.txt 和 f3.txt。我想对每个文件运行 script.awk,结果位于 bar/f1.txt、bar/f2.txt 和 bar/f3.txt 中
答案1
没什么太多的,循环遍历文件并将输出目录名作为文件名的前缀。
outputdir=bar
mkdir -p "$outputdir"
for f in ./*.txt; do
awk -f script.awk < "$f" > "$outputdir/$f"
done
这假设输入文件位于当前目录中,并且outputdir
是相对于该目录的。因此,如果您有foo/
和bar/
,在同一级别上,您需要cd foo
和 设置outputdir=../bar
。
如果不是这种情况,我们需要从 中删除输入目录名称$f
。前缀删除扩展${var#pattern}
在这里起作用:
outputdir=./bar
inputdir=./foo
mkdir -p "$outputdir"
for f in "$inputdir"/*.txt; do
awk -f script.awk < "$f" > "$outputdir/${f#"$inputdir"}"
done
"$outputdir/$(basename -- "$f")"
或者,如果您更熟悉的话,您可以使用类似的东西。 (如果您的目录名称不好听,请注意引号。)
答案2
使用 GNU awk 进行“就地”编辑:
cp -r foo bar &&
awk -i inplace 'script' bar/*
答案3
为了完整起见,如果您控制脚本,能在那里处理这个,例如
awk -vout=../bar/ '$2=="cow" {print "moo",$3,$1 > out FILENAME; next} $4!="fox" {print > out FILENAME}' *
但这通常会很麻烦,我个人会选择其他答案。作为埃德注意,除了 GNU awk 之外,您可能需要将相当小的内容分开-v
并用括号括起来,然后更改为并添加调用,我认为这是一个更糟糕的麻烦:-(>(out FILENAME)
>>
close(out FILENAME)