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
仅凭所展示的样品,请尝试以下内容。用GNUawk
编写和测试
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