如何在Linux上通过命令行向CSV文件中特定列的每一行添加前缀

如何在Linux上通过命令行向CSV文件中特定列的每一行添加前缀,csv,awk,text-editor,vi,Csv,Awk,Text Editor,Vi,我正在努力实现以下目标 在编辑之前先保存文件 column-1, column-2, column-3, column-4, column-5 Row-1-c1, Row-1-c2, Row-1-c3, Row-1-c4, Row-1-c5 Row-2-c1, Row-2-c2, Row-2-c3, Row-2-c4, Row-2-c5 Row-3-c1, Row-3-c2, Row-3-c3, Row-3-c4, Row-3-c5 Row-4-c1, Row-

我正在努力实现以下目标

在编辑之前先保存文件

column-1,  column-2,  column-3,  column-4,  column-5
Row-1-c1,  Row-1-c2,  Row-1-c3,  Row-1-c4,  Row-1-c5
Row-2-c1,  Row-2-c2,  Row-2-c3,  Row-2-c4,  Row-2-c5
Row-3-c1,  Row-3-c2,  Row-3-c3,  Row-3-c4,  Row-3-c5
Row-4-c1,  Row-4-c2,  Row-4-c3,  Row-4-c4,  Row-4-c5
Row-5-c1,  Row-5-c2,  Row-5-c3,  Row-5-c4,  Row-5-c5
编辑后的文件

column-1,   column-2,   column-3,           column-4,   column-5
Row-1-c1,   Row-1-c2,   Prefix-Row-1-c3,    Row-1-c4,   Row-1-c5
Row-2-c1,   Row-2-c2,   Prefix-Row-2-c3,    Row-2-c4,   Row-2-c5
Row-3-c1,   Row-3-c2,   Prefix-Row-3-c3,    Row-3-c4,   Row-3-c5
Row-4-c1,   Row-4-c2,   Prefix-Row-4-c3,    Row-4-c4,   Row-4-c5
Row-5-c1,   Row-5-c2,   Prefix-Row-5-c3,    Row-5-c4,   Row-5-c5
请注意,第3列是前缀添加到除列标题之外的每一行的列。
我想知道哪个编辑器是最好的编辑器,并了解如何使用命令来获得所需的结果

也许一个更好的问题是“你可以使用多少种不同的工具来完成这项工作?”

我可能会选择
awk
作为最简单的工具来完成这项工作:

awk -F, 'NR == 1 { print; OFS="," } NR > 1 { sub(/^ +/, "&Prefix-", $3); print }'
sub
操作在第3列开头的空格后添加
前缀-
。代码不试图调整第1行(标题)的内容;如果您希望在
$3
之后添加空格,那么我认为这就可以了(由于逗号的位置,您可以在第1行的第4列中添加额外空格的前缀):


你知道如何用sed做同样的事情吗

是的,像这样:

sed -e '  1s/^\(\([^,]*,[[:space:]]*\)\{3\}\)/\1       /' \
    -e '2,$s/^\(\([^,]*,[[:space:]]*\)\{2\}\)/\1Prefix-/' "$@"
第一个表达式处理第一行;它在第三列后面放置了与前缀中相同数量的空格(这里是“
prefix-
”,因此是7个空格)。第二个表达式处理剩余的行;它在第三列之前添加前缀

要处理列N而不是列3,请将3更改为N,将
\{2\}
中的2更改为N-1

我重新检查了第二个Awk脚本;它为我生成了问题样本数据的正确输出。因此,在其局限性范围内,第一个Awk脚本是这样做的。确保您使用的不是C shell(它会被多行带引号的字符串打乱),并且您在复制时非常小心

示例输出
也许一个更好的问题是“你可以使用多少种不同的工具来完成这项工作?”

我可能会选择
awk
作为最简单的工具来完成这项工作:

awk -F, 'NR == 1 { print; OFS="," } NR > 1 { sub(/^ +/, "&Prefix-", $3); print }'
sub
操作在第3列开头的空格后添加
前缀-
。代码不试图调整第1行(标题)的内容;如果您希望在
$3
之后添加空格,那么我认为这就可以了(由于逗号的位置,您可以在第1行的第4列中添加额外空格的前缀):


你知道如何用sed做同样的事情吗

是的,像这样:

sed -e '  1s/^\(\([^,]*,[[:space:]]*\)\{3\}\)/\1       /' \
    -e '2,$s/^\(\([^,]*,[[:space:]]*\)\{2\}\)/\1Prefix-/' "$@"
第一个表达式处理第一行;它在第三列后面放置了与前缀中相同数量的空格(这里是“
prefix-
”,因此是7个空格)。第二个表达式处理剩余的行;它在第三列之前添加前缀

要处理列N而不是列3,请将3更改为N,将
\{2\}
中的2更改为N-1

我重新检查了第二个Awk脚本;它为我生成了问题样本数据的正确输出。因此,在其局限性范围内,第一个Awk脚本是这样做的。确保您使用的不是C shell(它会被多行带引号的字符串打乱),并且您在复制时非常小心

示例输出
数据中是否存在任何复杂因素,如值中双引号内出现的逗号?(
第N-C1行,“第N-C2行,A部分,B部分”,第N-C3行,第N-C4行,第N-C5行
)。另外,示例数据中的空格有多重要?您似乎希望前缀出现在标记第3列开头的逗号后的前导空格之后-是否正确?数据中是否有任何复杂因素,例如值中双引号内出现的逗号?(
第N-C1行,“第N-C2行,A部分,B部分”,第N-C3行,第N-C4行,第N-C5行
)。另外,示例数据中的空格有多重要?您似乎希望前缀出现在标记第3列开始的逗号后的前导空格之后-是否正确?+1:其他选项是简单地将输出管道连接到
列-t
awk'BEGIN{FS=OFS=“,”}NR>1{sub(/^+/,“&Prefix-”,$3)}1'文件| column-t
@jonathan:你知道如何使用sed做同样的事情吗?@mOna:是的,但这很可怕,结果是一个难以理解的反斜杠和圆括号集合。你确定你真的需要知道吗?有没有一个很好的理由不能使用Awk?如果有令人信服的理由(比如“awk不可用”),那么说出来,我会解决的(这并不难,但不容易理解)。事实上,我对linuz和terminal的工作还很陌生。。。我想我需要了解sed和awk之间的区别。。我试过你的命令,但没用。。我认为这是我缺乏linux知识的问题。我不确定如果Awk失败,你会怎么做。请参阅
sed
中的更新以了解如何执行此操作。它在视觉上不是很好;不过,它非常有效。+1:另一种选择是将输出通过管道传输到
列-t
awk'BEGIN{FS=OFS=“,”}NR>1{sub(/^+/,“&Prefix-”,$3)}1'文件| column-t
@jonathan:你知道如何使用sed做同样的事情吗?@mOna:是的,但这很可怕,结果是一个难以理解的反斜杠和圆括号集合。你确定你真的需要知道吗?有没有一个很好的理由不能使用Awk?如果有令人信服的理由(比如“awk不可用”),那么说出来,我会解决的(这并不难,但不容易理解)。事实上,我对linuz和terminal的工作还很陌生。。。我想我需要了解sed和awk之间的区别。。我试过你的命令,但没用。。我认为这是我缺乏linux知识的问题。我不确定如果Awk失败,你会怎么做。请参阅
sed
中的更新以了解如何执行此操作。它在视觉上不是很好;不过,这是相当有效的。