在awk shell命令中替换变量中的特殊字符

时间:2014-07-29 14:05:51

标签: bash shell unix awk

我目前正在执行以下命令:

awk 'BEGIN { FS="," ; getline ; H=$0 } N != $3 { N=$3 ; print H > "/Directory/FILE_"$3"_DOWNLOAD.csv" } { print > "/Directory/FILE_"$3"_DOWNLOAD.csv" }' /Directory/FILE_ALL_DOWNLOAD.csv

这将从CSV文件中的第三个位置获取值,并为每个不同的$ 3值创建一个CSV。按需运作。

输入文件如下所示:

Name, Amount, ID
"ABC", "100.00", "0000001"
"DEF", "50.00", "0000001"
"GHI", "25.00", "0000002"

不幸的是我无法控制源(CSV)表中的值,$ 3值,但我想从中消除特殊(非字母数字)字符。我尝试了以下方法来完成此任务但失败了......

awk 'BEGIN { FS="," ; getline ; H=$0 } N != $3 { N=$3 ; name=${$3//[^a-zA-Z_0-9]/}; print H > "/Directory/FILE_"$name"_DOWNLOAD.csv" } { print > "/Directory/FILE_"$name"_DOWNLOAD.csv" }' /Directory/FILE_ALL_DOWNLOAD.csv

连连呢?我希望在一个命令中执行此操作,但是如果有人有一个可行的bash脚本答案。

4 个答案:

答案 0 :(得分:1)

如果您始终希望该数字位于CSV的最后一个字段中,并且您知道每个字段都用引号括起来,则可以使用此awk从您提供的输入中提取值456评论:

echo " 123.", "Company Name" " 456." | awk -F'[^a-zA-Z0-9]+' 'NF { print $(NF-1) }'

这将字段分隔符定义为任意数量的非字母数字字符,并检索倒数第二个字段。

如果这足以可靠地检索值,您可以像这样构建文件名:

file = "/Directory/FILE_" $(NF-1) "_DOWNLOAD.csv"

并输出它,就像你现在一样。

答案 1 :(得分:1)

这绝对不是您应该使用getline的工作,请参阅http://awk.info/?tip/getline

看起来你只想在每个3美元命名的文件中重现输入文件的第一行。那是:

awk -F, '
NR==1 { hdr=$0; next }
$3 != prev { prev=name=$3; gsub(/[^[:alnum:]_]/,"",name); $0 = hdr "\n" $0 }
{ print > ("/Directory/FILE_" name "_DOWNLOAD.csv") }
' /Directory/FILE_ALL_DOWNLOAD.csv

请注意,您必须始终将输出重定向(>)右侧的表达式括起来,因为它不明确,否则不同的awk会表现不同。

如果您愿意,请随意将它们全部放回一行。

答案 2 :(得分:0)

bash变量扩展不会出现在单引号中。

它们也无法在awk变量上执行。

据说你不需要这样做。

awk具有可执行相同任务的字符串操作函数。在这种情况下,您可能需要gsub函数。

答案 3 :(得分:0)

这会不适合您的要求吗?

awk -F, 'a=NR==1{x=$0;next}
!a{gsub(/[^[:alnum:]]/,"",$3);print x"\n"$0 >> "/Directory/FILE_"$3"_DOWNLOAD.csv"}' file