Unix剪切:两次打印相同的字段

时间:2012-09-13 11:22:30

标签: shell unix sed cut

说我有文件 - a.csv

ram,33,professional,doc
shaym,23,salaried,eng

现在我需要这个输出(请不要问我为什么)

ram,doc,doc,
shayam,eng,eng,

我正在使用剪切命令

cut -d',' -f1,4,4 a.csv

但输出仍然是

ram,doc
shyam,eng

这意味着 cut 只能打印一次一个字段。我需要打印两次相同的字段或 n 次。有什么黑客攻击吗?我只能使用cut或sed命令(请不要使用awk或perl)。 我为什么需要这个?(可选阅读) 啊。说来话长。我有这样的文件

#,#,-,-
#,#,#,#,#,#,#,-
#,#,#,-

我必须将其转换为

#,#,-,-,-,-,-
#,#,#,#,#,#,#,-
#,#,#,-,-,-,-

这里每个'#'和' - '指的是不同的数值数据。感谢。

5 个答案:

答案 0 :(得分:8)

您无法两次打印相同的字段。 cut按顺序打印选择的字段(或字符或字节)。有关非常类似的请求,请参阅Combining 2 different cut outputs in a single command?Reorder fields/characters with cut command

如果您的CSV在字段周围没有引号,则此处使用的正确工具是awk。

awk -F , -v OFS=, '{print $1, $4, $4}'

如果您不想使用awk(为什么?奇怪的系统有cutsed但没有awk?),您可以使用sed(仍然假设您的CSV字段周围没有引号)。匹配前四个以逗号分隔的字段,然后按所需顺序选择所需的字段。

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

答案 1 :(得分:1)

$ sed 's/,.*,/,/; s/\(,.*\)/\1\1,/' a.csv
ram,doc,doc,
shaym,eng,eng,

这是做什么的:

  • 只用逗号
  • 替换第一个和最后一个逗号之间的所有内容
  • 重复最后一个“,某事”部分并加上逗号。瞧!

做出的假设:

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

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

答案 2 :(得分:1)

正如其他人所说,cut不支持字段重复。

您可以合并cutsed,例如,如果重复的元素在最后:

< a.csv cut -d, -f1,4 | sed 's/,[^,]*$/&&,/'

输出:

ram,doc,doc,
shaym,eng,eng,

修改

要制作重复变量,你可以这样做(假设你有coreutils可用):

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,

答案 3 :(得分:1)

使用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

答案 4 :(得分:0)

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

awk -v OFS='\t' '$2=$2"\t"$2' # for tab-delimited files

对于CSV,您可以使用

awk -F , -v OFS=, '$2=$2","$2'