awk 使用 shell 参数或 shell 变量将输出打印到目录
awk print output to a directory using shell argument or shell variable
如何使用 shell 参数或命令参数将输出打印到 awk 中的目录?
Shell 程序调用并将参数传递给 awk 程序:
testshell.sh
shelloutputdir="./ouputdir/"
./testawk inputfile.txt ./outputdir/
awk 程序:
测试
#!/usr/bin/awk -f
{
print FILENAME > "./outputdir/outputfile1.txt"
fn2="outputfile2.txt"
fn3="outputfile3.txt"
fn4="outputfile4.txt"
print FILENAME > ARGV[2]"/"fn2
print FILENAME > ARGV[2]"subdir/"fn3
print FILENAME > $shelloutputdir"subdir/"fn4
}
注:
inputfile.txt
只是一个示例,因为 shell 和 awk 程序将处理其他参数。
输出目录已经存在。
./outputdir/
./outputdir/subdir/
输出:
./outputdir/outputfile1.txt
./outputdir/outputfile2.txt
./outputdir/subdir/outputfile3.txt
outputfile4.txt
未创建
错误:
awk: ./testawk:9: (FILENAME=inputfile.txt FNR=1) fatal: can't redirect to `input text filesubdir/outputfile4.txt' (No such file or directory)
问题汇总:
如何在 awk 中显式设置输出目录?
如何使用命令行参数在awk中设置输出目录?
awk中不存在的目录如何创建?
如何将 shell 变量传递给 awk 变量以设置输出目录?
感谢帮助和任何示例方法
注:
* 此答案基于使用 shebang 行 的 独立 awk
脚本(#!/usr/bin/awk -f
).
* 展示了如何从 shell 脚本 调用 awk
作为替代方法,这有其优点。
在 script 操作数 之后传递给 awk
的所有操作数(这隐含地是独立脚本本身, 在这种情况下) 默认解释为 输入文件.
鉴于 ./outputdir/
根据定义是一个 目录 ,它不能充当输入 文件 ,它是为什么你会收到警告。
但是,Awk 提供 伪文件名操作数语法 <var>=<value>
,而不是传递 filename, 定义了一个Awk variable,类似于pre-script -v <var>=<value>
option 语法(假设您的调用是通过 shebang 行进行的,基于 -v
选项的变量赋值是 not一个选项)。
请注意,这些 赋值是在 post 脚本操作数列表中遇到 时发生的,因此您需要 放置它们在 处理依赖于它们的实际输入文件之前:
shelloutputdir="./outputdir/"
./testawk odir="$shelloutputdir" inputfile.txt # Note the definition of variable `odir`
您可以通过这种方式定义的变量数量没有限制,但是,至少在假设上,您受到命令行最大总长度的限制,该值接近,但少于 getconf ARG_MAX
报告的内容。
上面定义了 Awk 变量 odir
,因此您的脚本需要引用它:
#!/usr/bin/awk -f
{
fn3="outputfile3.txt"
print FILENAME > (odir "subdir/" fn3)
}
正如Ed Morton指出的那样,如果输出文件名是根据表达式计算得出的,那么表达式应该包含在(...)
用于稳健性;虽然它在 某些 Awk 实现(例如 GNU Awk 和 Mawk)中也可以在没有括号的情况下工作,但它会在其他实现中中断(例如 BSD/macOS Awk)。
Awk POSIX spec 不规范这种情况下的行为。
- How do I explicitly set the output directory in awk?
没有 Awk 内部机制,但您可以使用 shell 到 cd
到输出目录 之前.
- How do I use a command line parameter to set the output directory in awk?
参见上面的解决方案。 Awk 中没有特殊的输出目录参数,但您可以将输出目录路径作为 Awk 变量.
传递
- How do I create a directory if it does not exist in awk?
没有 Awk 内部机制,但是 - 如果创建目录。在 shell 中提前不是一个选项 - 您可以使用 system()
函数来调用 mkdir
;例如:
# If the dir. name never contains ' (single quotes):
awk -v odir="out-dir" 'BEGIN { system("mkdir 7" odir "7") }'
# *From inside your stand-alone Awk script only*, you don't need 7 to represent
# ' chars - see below.
system("mkdir '" odir "'")
# Otherwise, more work is needed:
awk -v odir="out'dir" '
function shellQuote(s) { gsub("7", "7\77", s); return "7" s "7" }
BEGIN { system("mkdir " shellQuote(odir)) }
'
7
是表示'
的八进制转义序列,必须在显式调用awk
时使用,从shell,因为 '...'
已经被用来将 脚本作为一个整体包含起来 ,这会阻止使用 embedded '
字符。完全一样,因为单引号 shell 字符串不支持它。
这是 独立 awk
脚本优于来自 shell 的显式 awk
调用的一个方面:您可以在独立脚本中自由使用文字 '
实例 - 不需要 7
.
- How do I pass a shell variable to an awk variable to set the output directory?
查看问题 #2 的答案。
使用 shebang 执行 awk 脚本只会让你的生活更艰难,不要这样做。如果去掉 shebang 并将 "testawk" 写为:
odir=""
shift
/usr/bin/awk -v odir="$odir" '
{
print FILENAME > (odir "outputfile1.txt")
fn2="outputfile2.txt"
fn3="outputfile3.txt"
fn4="outputfile4.txt"
print FILENAME > (odir fn2)
print FILENAME > (odir "subdir/" fn3)
print FILENAME > (odir "subdir/" fn4)
}
' "$@"
那么你可以这样称呼它:
shelloutputdir="./outputdir/"
./testawk "$shelloutputdir" inputfile.txt
或者做任何你喜欢的事。关键是,不使用 shebang 可以让您将 awk 与 shell args 和 awk 文件名与 awk 变量初始值分开。
您可以创建一个目录,其名称存储变量 foo
和
system("mkdir -p 7" foo "7")
如何使用 shell 参数或命令参数将输出打印到 awk 中的目录?
Shell 程序调用并将参数传递给 awk 程序:
testshell.sh
shelloutputdir="./ouputdir/"
./testawk inputfile.txt ./outputdir/
awk 程序:
测试
#!/usr/bin/awk -f
{
print FILENAME > "./outputdir/outputfile1.txt"
fn2="outputfile2.txt"
fn3="outputfile3.txt"
fn4="outputfile4.txt"
print FILENAME > ARGV[2]"/"fn2
print FILENAME > ARGV[2]"subdir/"fn3
print FILENAME > $shelloutputdir"subdir/"fn4
}
注:
inputfile.txt
只是一个示例,因为 shell 和 awk 程序将处理其他参数。
输出目录已经存在。
./outputdir/
./outputdir/subdir/
输出:
./outputdir/outputfile1.txt
./outputdir/outputfile2.txt
./outputdir/subdir/outputfile3.txt
outputfile4.txt
未创建
错误:
awk: ./testawk:9: (FILENAME=inputfile.txt FNR=1) fatal: can't redirect to `input text filesubdir/outputfile4.txt' (No such file or directory)
问题汇总:
如何在 awk 中显式设置输出目录?
如何使用命令行参数在awk中设置输出目录?
awk中不存在的目录如何创建?
如何将 shell 变量传递给 awk 变量以设置输出目录?
感谢帮助和任何示例方法
注:
* 此答案基于使用 shebang 行 的 独立 awk
脚本(#!/usr/bin/awk -f
).
* awk
作为替代方法,这有其优点。
在 script 操作数 之后传递给 awk
的所有操作数(这隐含地是独立脚本本身, 在这种情况下) 默认解释为 输入文件.
鉴于 ./outputdir/
根据定义是一个 目录 ,它不能充当输入 文件 ,它是为什么你会收到警告。
但是,Awk 提供 伪文件名操作数语法 <var>=<value>
,而不是传递 filename, 定义了一个Awk variable,类似于pre-script -v <var>=<value>
option 语法(假设您的调用是通过 shebang 行进行的,基于 -v
选项的变量赋值是 not一个选项)。
请注意,这些 赋值是在 post 脚本操作数列表中遇到 时发生的,因此您需要 放置它们在 处理依赖于它们的实际输入文件之前:
shelloutputdir="./outputdir/"
./testawk odir="$shelloutputdir" inputfile.txt # Note the definition of variable `odir`
您可以通过这种方式定义的变量数量没有限制,但是,至少在假设上,您受到命令行最大总长度的限制,该值接近,但少于 getconf ARG_MAX
报告的内容。
上面定义了 Awk 变量 odir
,因此您的脚本需要引用它:
#!/usr/bin/awk -f
{
fn3="outputfile3.txt"
print FILENAME > (odir "subdir/" fn3)
}
正如Ed Morton指出的那样,如果输出文件名是根据表达式计算得出的,那么表达式应该包含在(...)
用于稳健性;虽然它在 某些 Awk 实现(例如 GNU Awk 和 Mawk)中也可以在没有括号的情况下工作,但它会在其他实现中中断(例如 BSD/macOS Awk)。
Awk POSIX spec 不规范这种情况下的行为。
- How do I explicitly set the output directory in awk?
没有 Awk 内部机制,但您可以使用 shell 到 cd
到输出目录 之前.
- How do I use a command line parameter to set the output directory in awk?
参见上面的解决方案。 Awk 中没有特殊的输出目录参数,但您可以将输出目录路径作为 Awk 变量.
传递
- How do I create a directory if it does not exist in awk?
没有 Awk 内部机制,但是 - 如果创建目录。在 shell 中提前不是一个选项 - 您可以使用 system()
函数来调用 mkdir
;例如:
# If the dir. name never contains ' (single quotes):
awk -v odir="out-dir" 'BEGIN { system("mkdir 7" odir "7") }'
# *From inside your stand-alone Awk script only*, you don't need 7 to represent
# ' chars - see below.
system("mkdir '" odir "'")
# Otherwise, more work is needed:
awk -v odir="out'dir" '
function shellQuote(s) { gsub("7", "7\77", s); return "7" s "7" }
BEGIN { system("mkdir " shellQuote(odir)) }
'
7
是表示'
的八进制转义序列,必须在显式调用awk
时使用,从shell,因为 '...'
已经被用来将 脚本作为一个整体包含起来 ,这会阻止使用 embedded '
字符。完全一样,因为单引号 shell 字符串不支持它。
这是 独立 awk
脚本优于来自 shell 的显式 awk
调用的一个方面:您可以在独立脚本中自由使用文字 '
实例 - 不需要 7
.
- How do I pass a shell variable to an awk variable to set the output directory?
查看问题 #2 的答案。
使用 shebang 执行 awk 脚本只会让你的生活更艰难,不要这样做。如果去掉 shebang 并将 "testawk" 写为:
odir=""
shift
/usr/bin/awk -v odir="$odir" '
{
print FILENAME > (odir "outputfile1.txt")
fn2="outputfile2.txt"
fn3="outputfile3.txt"
fn4="outputfile4.txt"
print FILENAME > (odir fn2)
print FILENAME > (odir "subdir/" fn3)
print FILENAME > (odir "subdir/" fn4)
}
' "$@"
那么你可以这样称呼它:
shelloutputdir="./outputdir/"
./testawk "$shelloutputdir" inputfile.txt
或者做任何你喜欢的事。关键是,不使用 shebang 可以让您将 awk 与 shell args 和 awk 文件名与 awk 变量初始值分开。
您可以创建一个目录,其名称存储变量 foo
和
system("mkdir -p 7" foo "7")