Awk 如何在CLI上用逗号替换某些行\n

Awk 如何在CLI上用逗号替换某些行\n,awk,sed,Awk,Sed,我有下面的文本文件 # This is a test 1 "watch" "autoconf" # This is another line 2 "coreutils" "binutils" "screen" # This is another line 3 "bash" "emacs&qu

我有下面的文本文件

 # This is a test 1
    "watch"
    "autoconf"

    # This is another line 2
    "coreutils"
    "binutils"
    "screen"

    # This is another line 3
    "bash"
    "emacs"
    "nano"
    "bison"

    #  This is another line 4
    "libressl"
    "python"
    "rsync"
    "unzip"
    "vim"
我想将此更改为以下内容:

# This is a test 1
watch, autoconf

# This is another line 2
coreutils, binutils, screen

# This is another line 3
bash, emacs, nano, bison

#  This is another line 4
libressl, python, rsync, unzip, vim
删除前导空格,删除引号,用逗号替换新行

到目前为止,我得到了这个:

$ cat in.txt | sed 's/"//g' | sed 's/^[[:space:]]*//'> out.txt
我不知道如何用逗号替换新行。我尝试了以下方法

# no change
$ cat in.txt | sed 's/"//g' | sed 's/^[[:space:]]*//'| sed  's/\n/,/g'> out.txt

# changed all new lines
$ cat in.txt | sed 's/"//g' | sed 's/^[[:space:]]*//'| sed -z 's/\n/,/g'> out.txt
$ cat out.txt
# This is a test 1,watch,autoconf,,# This is another line 2,coreutils,binutils,screen,,# This is another line 3,bash,emacs,nano,bison,,#  This is another line 4,libressl,python,rsync,unzip,vim


如何实现这一点?

使用GNU
sed的单行程序:

sed -Ez 's/\n[[:blank:]]*"?/\n/g; s/"\n([^\n])/, \1/g; s/"//g' file
或者,使用标准sed的多行技术:

sed '
    s/^[[:blank:]]*//
    /^".*"$/{
        s/.//
        s/.$//
        :a
        $b
        N
        s/\n[[:blank:]]*"\(.*\)"$/, \1/
        ta
    }' file
这可能适用于您(GNU-sed):

去掉所有行前面的空白

去掉双引号并将这些单词附加到保留空间


否则,切换到保留空间,删除第一个引入的换行符,用
替换所有其他换行符,打印结果,然后切换回图案空间并打印。

这是awk版本。注意,我们将记录分隔符
RS
设置为空字符串。这告诉awk将由空行分隔的每个块视为单个记录。然后,通过将带有
-F
的字段分隔符设置为换行符,块中的每一行将成为该记录中的单个字段

然后,我们只需通过每个记录的字段,使用
sub
gsub
删除前导空格和引号,并在不需要换行符时使用
printf
避免换行符,而是打印逗号

$ awk -v RS="" -F'\n'  '{
  sub(/^[[:space:]]*/, "", $1);       
  print $1; 
  sep=""; 
  for (i=2; i<=NF; ++i) { 
    gsub(/[[:space:]]*"/, "", $i); 
    printf "%s%s", sep, $i; 
    sep=", " 
  } 
  print "\n"
}' file

仅凭所展示的样品,请尝试以下内容。用GNU
awk
编写和测试

awk '
BEGIN{
  OFS=", "
}
NF{
  gsub(/"|^ +| +$/,"")
}
/^#/ || !NF{
  if(value){
    print first ORS value
  }
  first=$0
  value=""
  if(!NF){ print }
  next
}
{
  value=(value?value OFS:"")$0
}
END{
  if(value){
    print first ORS value
  }
}
'  Input_file
说明:添加上述内容的详细说明

awk '                             ##Starting awk program from here.
BEGIN{                            ##Starting BEGIN section of this program from here.
  OFS=", "                        ##Setting OFS as comma space here.
}
NF{                               ##Checking condition if line is NOT empty do following.
  gsub(/"|^ +| +$/,"")            ##Globally substituting " OR starting/ending spaces with NULL here.
}
/^#/ || !NF{                      ##Checking condition if line starts from # OR line is NULL then do following.
  if(value){                      ##Checking condition if value is NOT NULL then do following.
    print first ORS value         ##Printing first ORS value values here.
  }
  first=$0                        ##Setting first to current line here.
  value=""                        ##Nullifying value here.
  if(!NF){ print }                ##Checking condition if line is empty then simply print it.
  next                            ##next will skip all further statements from here.
}
{
  value=(value?value OFS:"")$0    ##Creating value here and keep on adding current line value to it.
}
END{                              ##Starting END block of this program from here.
  if(value){                      ##Checking condition if value is NOT NULL then do following.
    print first ORS value         ##Printing first ORS value values here.
  }
}
' Input_file                      ##Mentioning Input_file name here.

在每个Unix设备上的任意shell中使用任意POSIX awk:

$ awk -v RS= -v ORS='\n\n' -F'[[:blank:]]*\n[[:blank:]]*' -v OFS=', ' '{
    gsub(/^[[:blank:]]*|"/,"")
    printf "%s\n", $1
    for (i=2;i<=NF;i++) {
        printf "%s%s", $i, (i<NF ? OFS : ORS)
    }
}' file
# This is a test 1
watch, autoconf

# This is another line 2
coreutils, binutils, screen

# This is another line 3
bash, emacs, nano, bison

#  This is another line 4
libressl, python, rsync, unzip, vim
$awk-vrs=-vrs='\n\n'-F'[:blank:][]*\n[:blank:][]*'-v OFS=',''{
gsub(/^[:blank:][]*|“/,”)
printf“%s\n”,$1

对于(i=2;iIs,您显示的输入中的缩进是否正确?所有缩进的第一行?请尝试
sed-Ez的/(”)\n([^\n])/\1,2/g'文件
@BenjaminW。是的,是这样的。Wiktor不起作用。它的输出与我的第一行相同。
FS
的完美设置。
awk '
BEGIN{
  OFS=", "
}
NF{
  gsub(/"|^ +| +$/,"")
}
/^#/ || !NF{
  if(value){
    print first ORS value
  }
  first=$0
  value=""
  if(!NF){ print }
  next
}
{
  value=(value?value OFS:"")$0
}
END{
  if(value){
    print first ORS value
  }
}
'  Input_file
awk '                             ##Starting awk program from here.
BEGIN{                            ##Starting BEGIN section of this program from here.
  OFS=", "                        ##Setting OFS as comma space here.
}
NF{                               ##Checking condition if line is NOT empty do following.
  gsub(/"|^ +| +$/,"")            ##Globally substituting " OR starting/ending spaces with NULL here.
}
/^#/ || !NF{                      ##Checking condition if line starts from # OR line is NULL then do following.
  if(value){                      ##Checking condition if value is NOT NULL then do following.
    print first ORS value         ##Printing first ORS value values here.
  }
  first=$0                        ##Setting first to current line here.
  value=""                        ##Nullifying value here.
  if(!NF){ print }                ##Checking condition if line is empty then simply print it.
  next                            ##next will skip all further statements from here.
}
{
  value=(value?value OFS:"")$0    ##Creating value here and keep on adding current line value to it.
}
END{                              ##Starting END block of this program from here.
  if(value){                      ##Checking condition if value is NOT NULL then do following.
    print first ORS value         ##Printing first ORS value values here.
  }
}
' Input_file                      ##Mentioning Input_file name here.
$ awk -v RS= -v ORS='\n\n' -F'[[:blank:]]*\n[[:blank:]]*' -v OFS=', ' '{
    gsub(/^[[:blank:]]*|"/,"")
    printf "%s\n", $1
    for (i=2;i<=NF;i++) {
        printf "%s%s", $i, (i<NF ? OFS : ORS)
    }
}' file
# This is a test 1
watch, autoconf

# This is another line 2
coreutils, binutils, screen

# This is another line 3
bash, emacs, nano, bison

#  This is another line 4
libressl, python, rsync, unzip, vim