我有8个awk表达式,只有我正在搜索的2种模式不同。所以我然后创建了一个awk函数来改进我的代码,但现在它不会工作。我正在做的是......
printFmt () {
awk -v MYPATH="$MYPATH" -v FILE_EXT="$FILE_EXT" -v NAME_OF_FILE="$NAME_OF_FILE" -v DATE="$DATE" -v PATTERN="$1" -v SEARCH="$2" '
$0 ~ PATTERN {
rec = $1 OFS $2 OFS $4 OFS $7
for (i=9; i<=NF; i++) {
rec = rec OFS $i
if ($i ~ SEARCH) {
break
}
}
print rec >> "'$MYPATH''$NAME_OF_FILE''$DATE'.'$FILE_EXT'"
}
' "$FILE_LOCATION"
}
并使用printFmt "$STORED_PROCS_FINISHED" "/([01])/"
致电。我的代码完全在上面,除了SEARCH它是/([01])/。是否有一些我缺少的语法?
答案 0 :(得分:2)
请阅读Arnold Robbins撰写的有效Awk编程,第4版:
printFmt () {
awk -v regexp1="$1" -v regexp2="$2" '
$0 ~ regexp1 {
rec = $1 OFS $2 OFS $4 OFS $7
for (i=9; i<=NF; i++) {
rec = rec OFS $i
if ($i ~ regexp2) {
break
}
}
print rec
}
' "$FILE_LOCATION" >> "${MYPATH}${NAME_OF_FILE}${DATE}.${FILE_EXT}"
}
printFmt "$STORED_PROCS_FINISHED" "[01]"
您对变量名使用全部大写字母很糟糕 - 仅适用于导出的shell变量。
请勿使用&#34; pattern&#34;因为它含糊不清,而且搜索&#34;没有意义 - 为我命名为regexp1和regexp2的变量提出两个有意义的名称。
答案 1 :(得分:1)
如评论中所述:
您应该省略作为参数传递的正则表达式的斜杠。传递"([01])"
代替"/([01])/"
应该可以正常工作。我不相信括号也是必要的;只有"[01]"
也应该有用。
您将-v
的值传递给awk
脚本中未使用的awk
脚本。您有shell使用这些值来创建文件名。您应该不将值传递给awk
,或者不应该使用shell来创建文件名。
鉴于这些评论,我认为您的代码可能是:
printFmt() {
awk -v PATTERN="$1" -v SEARCH="$2" '
$0 ~ PATTERN {
rec = $1 OFS $2 OFS $4 OFS $7
for (i=9; i<=NF; i++) {
rec = rec OFS $i
if ($i ~ SEARCH) {
break
}
}
print rec
}
' "$FILE_LOCATION" >> "$MYPATH$NAME_OF_FILE$DATE.$FILE_EXT"
}
printFmt "$STORED_PROCS_FINISHED" "[01]"
除非每次调用函数时构造的文件名都会改变,否则我会在函数外部创建一次文件名,并在函数外部使用它:
printFmt() {
awk -v PATTERN="$1" -v SEARCH="$2" '
$0 ~ PATTERN {
rec = $1 OFS $2 OFS $4 OFS $7
for (i=9; i<=NF; i++) {
rec = rec OFS $i
if ($i ~ SEARCH) {
break
}
}
print rec
}
' "$FILE_LOCATION"
}
OUTFILE="$MYPATH$NAME_OF_FILE$DATE.$FILE_EXT"
printFmt "$STORED_PROCS_FINISHED" "[01]" >> "$OUTFILE"
…7 other calls to printFmt each with I/O redirection…
甚至:
{
printFmt "$STORED_PROCS_FINISHED" "[01]"
…7 other calls to printFmt…
} >> "$OUTFILE"
总的来说,我可能会将要扫描的文件作为参数传递给函数:
printFmt() {
pattern="${1:?}"
search="${2:?}"
shift 2
awk -v PATTERN="$pattern1" -v SEARCH="$search" '
$0 ~ PATTERN {
rec = $1 OFS $2 OFS $4 OFS $7
for (i=9; i<=NF; i++) {
rec = rec OFS $i
if ($i ~ SEARCH) {
break
}
}
print rec
}
' "$@" # All the remaining arguments
}
{
printFmt "$STORED_PROCS_FINISHED" "[01]" "$FILE_LOCATION"
…7 other calls to printFmt…
} >> "$OUTFILE"
这为数据的来源和转移提供了最大的灵活性。如果没有提供文件名参数,它允许函数读取其标准输入。如果${1:?}
未设置为非空字符串,则$1
表示法将生成错误;这是检查参数1(模式)是否已提供给函数的粗略但有效的方法。与搜索参数类似。错误消息不会提供非常丰富的信息,但任何消息可能比在未提供值时尝试继续更好。