我目前正在执行以下命令:
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脚本答案。
答案 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