Shell Unix剪切:打印同一字段两次

Shell Unix剪切:打印同一字段两次,shell,unix,sed,cut,Shell,Unix,Sed,Cut,假设我有文件-a.csv ram,33,professional,doc shaym,23,salaried,eng 现在我需要这个输出(请不要问我为什么) 我正在使用cut命令 cut -d',' -f1,4,4 a.csv 但产出仍然存在 ram,doc shyam,eng 这意味着cut只能一次打印字段。我需要打印同一字段两次或n次。 我为什么需要这个?(阅读时可选) 啊。说来话长。我有一个这样的文件 #,#,-,- #,#,#,#,#,#,#,- #,#,#,- 我得把这个秘密告

假设我有文件-a.csv

ram,33,professional,doc
shaym,23,salaried,eng
现在我需要这个输出(请不要问我为什么)

我正在使用cut命令

cut -d',' -f1,4,4 a.csv
但产出仍然存在

ram,doc
shyam,eng
这意味着cut只能一次打印字段。我需要打印同一字段两次或n次。 我为什么需要这个?(阅读时可选) 啊。说来话长。我有一个这样的文件

#,#,-,-
#,#,#,#,#,#,#,-
#,#,#,-
我得把这个秘密告诉你

#,#,-,-,-,-,-
#,#,#,#,#,#,#,-
#,#,#,-,-,-,-
这里,每个“#”和“-”表示不同的数值数据。谢谢

$ sed 's/,.*,/,/; s/\(,.*\)/\1\1,/' a.csv
ram,doc,doc,
shaym,eng,eng,
它的作用是:

  • 用逗号替换第一个和最后一个逗号之间的所有内容
  • 重复最后一个“something”部分,并加上逗号。瞧
作出的假设:

  • 您需要第一个字段,然后是最后一个字段的两倍
  • 第一个和最后一个字段中没有转义逗号

为什么需要这个输出?:-)

同一字段不能打印两次<代码>剪切按顺序打印选定的字段(或字符或字节)。有关一些非常类似的请求,请参阅和

如果您的CSV字段周围没有引号,那么这里使用的正确工具是awk

awk -F , -v OFS=, '{print $1, $4, $4}'
如果您不想使用awk(为什么?哪个奇怪的系统有
cut
sed
但没有
awk
?),您可以使用sed(仍然假设您的CSV字段周围没有引号)。匹配前四个逗号分隔的字段,并按所需顺序选择所需的字段

sed -e 's/^\([^,]*\),\([^,]*\),\([^,]*\),\([^,]*\)/\1,\4,\4/'

正如其他人所指出的,
cut
不支持字段重复

您可以组合
cut
sed
,例如,如果重复元素位于末尾:

< a.csv cut -d, -f1,4 | sed 's/,[^,]*$/&&,/'
编辑 要创建repeation变量,可以执行以下操作(假设有coreutils可用):

使用perl:

perl -F, -ane 'chomp($F[3]);$a=$F[0].",".$F[3].",".$F[3];print $a."\n"' your_file
使用sed:

sed 's/\([^,]*\),.*,\(.*\)/\1,\2,\2/g' your_file

我也有同样的问题,但我没有将所有列添加到awk,而是使用(复制第2列):

awk-vofs='\t'$2=$2'\t'$2'#用于制表符分隔的文件

对于CSV,您可以使用


这是家庭作业吗?为什么你只能使用
cut
sed
?输出行必须以逗号结尾吗?你的意思是每行都应该有相同数量的字段吗?我是否在我的问题中附加了问题的范围。这是awk/中更好的解决方案,JensOne提供的关于awk和范围打印的sed解决方案就是它的一部分与切割相比,速度较慢。最好每行调用cut两次。@JohnJiang是真的,awk通常比sed慢,后者比cut等专用工具慢。您只会注意到非常大的文件(数百万条记录)。在我链接的其中一个线程中有一个剪切+粘贴解决方案,对于非常大的文件可能更快。
n=10
rep=$(seq $n | sed 's:.*:\&:' | tr -d '\n')
< a.csv cut -d, -f1,4 | sed 's/,[^,]*$/'"$rep"',/'
ram,doc,doc,doc,doc,doc,doc,doc,doc,doc,doc,
shaym,eng,eng,eng,eng,eng,eng,eng,eng,eng,eng,
perl -F, -ane 'chomp($F[3]);$a=$F[0].",".$F[3].",".$F[3];print $a."\n"' your_file
sed 's/\([^,]*\),.*,\(.*\)/\1,\2,\2/g' your_file