将多行字符串转换为单个逗号分隔

Posted

技术标签:

【中文标题】将多行字符串转换为单个逗号分隔【英文标题】:Turning multi-line string into single comma-separated 【发布时间】:2012-02-01 14:46:58 【问题描述】:

假设我有以下字符串:

something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

我如何把它变成简单的

+12.0,+15.5,+9.0,+13.5

在 bash 中?

【问题讨论】:

让我们退后一步,考虑一下这个线程是对 bash 作为编程语言的明显控诉。考虑 Scala 的 listOfStuff mkString ", " 或 Haskell 的 intercalate ", " listOfString 相关:Convert text file into a comma delimited string 【参考方案1】:

另一个 AWK 解决方案

运行

awk 'printf "%s", $c; while(getline)printf "%s%s", sep, $c' c=2 sep=','

使用第 2 列形成以逗号分隔的列表。像往常一样在标准输入中或作为文件名参数提供输入。

【讨论】:

【参考方案2】:

试试这个简单的代码:

awk 'printf("%s,",$2)' File1

【讨论】:

它添加了一个额外的逗号【参考方案3】:

这可能对你有用:

cut -d' ' -f5 file | paste -d',' -s
+12.0,+15.5,+9.0,+13.5

sed '/^.*\(+[^ ]*\).*/s//\1/;H;$x;s/\n/,/g;s/.//p;d' file
+12.0,+15.5,+9.0,+13.5

sed 's/\S\+\s\+//;s/\s.*//;H;$!d;x;s/.//;s/\n/,/g' file

对于文件中的每一行;砍掉第一个字段和后面的空格,砍掉第二个字段后面的行的其余部分并附加到保留空间。删除除我们交换到保留空间的最后一行之外的所有行,并在删除开头引入的换行符后,将所有换行符转换为,'s。

注意可以写成:

sed 's/\S\+\s\+//;s/\s.*//;1h;1!H;$!d;x;s/\n/,/g' file

【讨论】:

【参考方案4】:

干净简单:

awk 'print $2' file.txt | paste -s -d, -

【讨论】:

这是最好的答案,显然是正确的方法 如何用单/双引号引用每个值? @Hussain cat thing | awk -F',' ' print "'\''" $7 "'\' '" ' | paste -s -d ',' 如何使用,'作为分隔符? 如果字符串中有任何 CRLF,请记住处理 Windows 换行符(例如使用dos2unix)。【参考方案5】:

好吧,最难的部分可能是选择第二个“列”,因为我不知道有一种简单的方法可以将多个空格视为一个空格。其余的很容易。使用 bash 替换。

# cat bla.txt
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

# cat bla.sh
OLDIFS=$IFS
IFS=$'\n'
for i in $(cat bla.txt); do
  i=$(echo "$i" | awk 'print $2')
  u="$u:+$u, $i"
done
IFS=$OLDIFS
echo "$u"

# bash ./bla.sh
+12.0, +15.5, +9.0, +13.5

【讨论】:

【参考方案6】:

awk 一个班轮

$ awk 'printf (NR>1?",":"") $2' file

+12.0,+15.5,+9.0,+13.5

【讨论】:

格式说明符"%s", 应该在printf 之后添加以使其更健壮,即使其适用于所有类型的行,例如“foo %s”。【参考方案7】:

没有看到这个简单的 awk 解决方案

awk 'bb=b","b=b$2ENDprint b' infile

【讨论】:

【参考方案8】:
cat data.txt | xargs | sed -e 's/ /, /g'

【讨论】:

我也喜欢这样的解决方案,但这里是否需要 -e arg,因为只有第一个命令用于 sed?我相信cat data.txt | xargs | sed 's/ /, /g' 会一样工作。例如,echo -e "foo\nbar\nbazz" | xargs | sed 's/ /, /g' 输出 foo, bar, bazz【参考方案9】:

用纯 Bash 编写的解决方案:

#!/bin/bash

sometext="something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)"

a=()
while read -r a1 a2 a3; do
    # we can add some code here to check valid values or modify them
    a+=("$a2")
done <<< "$sometext"
# between parenthesis to modify IFS for the current statement only
(IFS=',' ; printf '%s: %s\n' "Result" "$a[*]")

结果:+12.0,+15.5,+9.0,+13.5

【讨论】:

您也可以使用read -r -a cols,然后将"$cols[1] 添加到列表a【参考方案10】:

你可以使用grep:

grep -o "+\S\+" in.txt | tr '\n' ','

查找以+ 开头的字符串,后跟任何字符串\S\+,然后将换行符转换为逗号。对于大文件,这应该很快。

【讨论】:

【参考方案11】:

另一个 Perl 解决方案,类似于 Dan Fego 的 awk:

perl -ane 'print "$F[1],"' file.txt | sed 's/,$/\n/'

-a 告诉 perl 将输入行拆分为 @F 数组,该数组从 0 开始索引。

【讨论】:

【参考方案12】:

试试这个:

sedSelectNumbers='s".* \(+[0-9]*[.][0-9]*\) .*"\1,"'
sedClearLastComma='s"\(.*\),$"\1"'
cat file.txt |sed "$sedSelectNumbers" |tr -d "\n" |sed "$sedClearLastComma"

好消息是删除换行符“\n”字符很容易!

编辑:使用 sed 将行合并为一行的另一种好方法是:|sed ':a;N;$!ba;s/\n/ /g' got from here。

【讨论】:

那个编辑很棒 - +1!【参考方案13】:

你也可以这样打印:

只是 awk:使用 printf

bash-3.2$ cat sample.log
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

bash-3.2$ awk '  if($2 != "")  if(NR==1)  printf $2  else  printf "," $2   ' sample.log
+12.0,+15.5,+9.0,+13.5

【讨论】:

【参考方案14】:

这应该也可以

awk 'print $2' file | sed ':a;N;s/\n/,/;ba'

【讨论】:

【参考方案15】:
$ awk -v ORS=, 'print $2' data.txt | sed 's/,$//'
+12.0,+15.5,+9.0,+13.5

$ cat data.txt | tr -s ' ' | cut -d ' ' -f 2 | tr '\n' ',' | sed 's/,$//'
+12.0,+15.5,+9.0,+13.5

【讨论】:

干杯,如果 awk 的输入是通过标准输入(只需在您的示例中输入 function | awk...【参考方案16】:

你也可以通过两个 sed 调用来做到这一点:

$ cat file.txt 
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)
$ sed 's/^[^:]*: *\([+0-9.]\+\) .*/\1/' file.txt | sed -e :a -e '$!N; s/\n/,/; ta'
+12.0,+15.5,+9.0,+13.5

第一个 sed 调用删除不感兴趣的数据,第二个加入所有行。

【讨论】:

【参考方案17】:

使用 perl:

fg@erwin ~ $ perl -ne 'push @l, (split(/\s+/))[1]; END  print join(",", @l) . "\n" ' <<EOF
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)
EOF

+12.0,+15.5,+9.0,+13.5

【讨论】:

【参考方案18】:

您可以使用awksed

awk -vORS=, ' print $2 ' file.txt | sed 's/,$/\n/'

或者如果你想使用管道:

echo "data" | awk -vORS=, ' print $2 ' | sed 's/,$/\n/'

分解:

awk 擅长处理细分为字段的数据 -vORS=, 将“输出记录分隔符”设置为 ,,这正是您想要的 print $2 告诉 awk 打印每条记录(行)的第二个字段 file.txt 是你的文件名 sed 只是去掉了尾随的 , 并将其变成一个换行符(如果你不想换行符,你可以这样做 s/,$//

【讨论】:

awk: 无效的 -v 选项 :( 在 -v 和 ORS= 之间添加一个空格,(对我来说,在 osx 上) 如何执行相同的命令来分离管道? awk -v ORS=| ' print $1 ' DCMC.rtf | sed 's/,$/\n/' 遇到错误 奇怪的是,当我尝试这样做时,输出为空。 我认为管道版本应该是 print $1 否则我在输出中只会得到逗号

以上是关于将多行字符串转换为单个逗号分隔的主要内容,如果未能解决你的问题,请参考以下文章

如何将包含逗号分隔的 json 值的单个字符串转换为单个 json 对象?

使用 Python 将多个字符串元素列表转换为单个元素以逗号分隔的列表

将多行转换为雪花中的一个逗号分隔值

Bash将多行字符串转换为单个换行符分隔的字符串[重复]

将逗号分隔值转换为双引号逗号分隔字符串

使用逗号分隔符将单个 CSV 列批量转换为多个