我们想要将 csv 行中的每个字符串分隔开
线路示例(可以是其他线路,具有相同的概念)
machine23,machine094,machine73,machine83
所以我们试试这个
echo machine23,machine094,machine73,machine83 |awk -F"," '{for(i=1;i<=NF;i++){printf "%-20s", $i};printf "\n"}'
但我们得到
machine23 machine094 machine7 machine83
而是得到以下预期结果
machine23
machine094
machine7
machine83
有什么建议么?
答案1
$ echo machine23,machine094,machine73,machine83 | tr ',' '\n'
machine23
machine094
machine73
machine83
或者如果您确实想在 awk 中执行此操作(也许是因为您想在 awk 中进行进一步处理):
$ echo machine23,machine094,machine73,machine83 | \
awk -F',' -v OFS='\n' '{$1=$1;$0=$0;print}'
machine23
machine094
machine73
machine83
这使用了一个巧妙的 awk 技巧,如果您更改任何字段(即使将其设置为等于自身,如 中$1=$
)然后设置$0=$0
,awk 将重新格式化整个输入行 - 将原始字段分隔符(FS
在本例中为逗号)替换为输出字段分隔符(OFS
在本例中为换行符)。
答案2
首先,本着教学的精神,这是您自己的逻辑的固定版本(为了易读而包装和间隔):
$ echo machine23,machine094,machine73,machine83 \
|awk -F"," '{ for (i = 1; i <= NF; i++) { printf "%-20s\n", $i } }'
machine23
machine094
machine73
machine83
因为您使用了%-20s
,所以这会添加一些尾随空白(选择上面的输出来查看它),但我所做的只是将 移到循环printf "\n"
内部。printf
for
由于您的版本只有很少的空白,所以这里有一个密码高尔夫使用您的逻辑解决方案:
echo machine23,machine094,machine73,machine83|awk -F, '{while(i<NF)print$++i}'
这是一个与字段无关的 awk 解决方案,使用全局替换而不需要循环:
$ echo machine23,machine094,machine73,machine83 |awk '{ gsub(/,/,"\n"); print }'
machine23
machine094
machine73
machine83
这模仿了以下 sed 解决方案:
$ echo machine23,machine094,machine73,machine83 |sed 's/,/\n/g'
machine23
machine094
machine73
machine83
上面两者都只是将逗号替换为换行符,就像CAS的tr解决方案。
这是一个 grep 解决方案:
$ echo machine23,machine094,machine73,machine83 |grep -o '[^,]*'
machine23
machine094
machine73
machine83
这让 grep show only ( -o
) 匹配非逗号文本,每个项目都在自己的行上。