Unix命令将单行中的多行数据与分隔符一起转换

时间:2013-05-22 07:11:44

标签: shell unix sed awk

以下是实际的文件数据:

abc
def
ghi
jkl
mno

所需的输出应采用以下格式:

'abc','def','ghi','jkl','mno'

我以前执行此操作的命令将输出显示为:

abc,def,ghi,jkl,mno

命令如下:

sed -n 's/[0-3]//;s/ //;p' Split_22_05_2013 | \
  awk -v ORS= '{print $0" ";if(NR%4==0){print "\n"}}'

8 个答案:

答案 0 :(得分:4)

为了回应sudo_O的评论,我在纯粹的bash中添加了awk解决方案。它根本不执行任何程序。当然,可以添加<<XXX ... XXX而不是<filename(此处为文档)。

set c=""
while read w; do
  echo -e "$c'$w'\c"
  c=,
done<<XXX
abc
def
ghi
jkl
mno
XXX

输出:

'abc','def','ghi','jkl','mno'

更短的版本:

printf -v out ",'%s'" $(<infile)
echo ${out:1}

没有可怕的管蛇你可以尝试这样的事情:

awk 'NR>1{printf ","}{printf "\x27%s\x27",$0}' <<XXX
abc
def
ghi
jkl
mno
XXX

输出:

'abc','def','ghi','jkl','mno'

或者将整个输入读作一行的其他版本:

awk -vRS="" '{gsub("\n","\x27,\x27");print"\x27"$0"\x27"}'

或者让awk更多地使用内部变量的版本

awk -vRS="" -F"\n" -vOFS="','" -vORS="'" '{$1=$1;print ORS $0}'

需要$1=$1;告诉awk使用新字段重新打包$0并记录分隔符(OFSORS)。

答案 1 :(得分:3)

$ cat test.txt
abc
def
ghi
jkl
mno

$ cat test.txt | tr '\n' ','
abc,def,ghi,jkl,mno,

$ cat test.txt | awk '{print "\x27" $1 "\x27"}' | tr '\n' ','
'abc','def','ghi','jkl','mno',

$ cat test.txt | awk '{print "\x27" $1 "\x27"}' | tr '\n' ',' | sed 's/,$//'
'abc','def','ghi','jkl','mno'

可以缩短最后一个命令以避免UUOC

$ awk '{print "\x27" $1 "\x27"}' test.txt | tr '\n' ',' | sed 's/,$//'
'abc','def','ghi','jkl','mno'

答案 2 :(得分:3)

单独使用sed

sed -n "/./{s/^\|\$/'/g;H}; \${x;s/\n//;s/\n/,/gp};" test.txt

编辑:已修复,它现在也可以使用或不使用空行。

答案 3 :(得分:2)

$ cat file 
abc
def
ghi
jkl
mno

$ cat file | tr '\n' ' ' | awk -v q="'" -v OFS="','" '$1=$1 { print q $0 q }'
'abc','def','ghi','jkl','mno'
  1. 将'\ n'替换为'' - &gt; (tr'\ n \'')
  2. 将每个分隔符(''空格)替换为(','quote-comma-quote) - &gt; (-v OFS =“','”)
  3. 在行的开头和结尾添加引号 - &gt; (打印q $ 0 q)

答案 4 :(得分:2)

这可以通过sed和paste简单地完成:

<infile sed "s/^\|\$/'/g" | paste -sd,

或更便携(我认为,现在无法测试):

sed "s/^\|\$/'/g" infile | paste -s -d , -

答案 5 :(得分:1)

$ sed "s/[^ ][^ ]*/'&',/g" input.txt | tr -d '\n'
'abc','def','ghi','jkl','mno',

要清理最后一个,,请输入

| sed 's/,$//'

答案 6 :(得分:1)

awk 'seen == 1 { printf("'"','"'%s", $1);} seen == 0 {seen = 1; printf("'"'"'%s", $1);} END { printf("'"'"'\n"); }'

稍微可读的格式(适用于awk -f):

# Print quote-terminator, separator, quote-start, thing
seen == 1 { printf("','%s", $1); }
# Set the "print separator" flag, print quote-start thing
seen == 0 { seen = 1; printf("'%s", $1}; }
END { printf("'\n"); } # Print quote-end

答案 7 :(得分:1)

 perl -l54pe 's/.*/\x27$&\x27/' file