gawk-使用自定义字符和无类似结尾字符分隔行

gawk-使用自定义字符和无类似结尾字符分隔行,awk,Awk,假设我有这样一个文件: test.txt one two three 我希望得到以下输出:1 | 2 | 3 我现在正在使用这个命令:gawk-vors='|'{print$0}'test.txt 其中给出:1 | 2 | 3 | 如何打印它,使最后一个|不在那里?这里有一种方法: $seq 1 | awk-v ORS='NR>1{print“|”}1;结束{打印“\n”} 1. $seq 3 | awk-v ORS='NR>1{print“|”}1;结束{打印“\n”} 1|2|3 用粘贴

假设我有这样一个文件:

test.txt

one
two
three
我希望得到以下输出:
1 | 2 | 3

我现在正在使用这个命令:
gawk-vors='|'{print$0}'test.txt

其中给出:
1 | 2 | 3 |


如何打印它,使最后一个
|
不在那里?

这里有一种方法:

$seq 1 | awk-v ORS='NR>1{print“|”}1;结束{打印“\n”}
1.
$seq 3 | awk-v ORS='NR>1{print“|”}1;结束{打印“\n”}
1|2|3
粘贴

$seq 1 |粘贴-sd'|'
1.
$seq 3 |粘贴-sd'|'
1|2|3

这里有一种方法:

$seq 1 | awk-v ORS='NR>1{print“|”}1;结束{打印“\n”}
1.
$seq 3 | awk-v ORS='NR>1{print“|”}1;结束{打印“\n”}
1|2|3
粘贴

$seq 1 |粘贴-sd'|'
1.
$seq 3 |粘贴-sd'|'
1|2|3

使用字段分隔符将一列转换为一行:

awk '{$1=$1} 1' FS='\n' OFS='|' RS='' file
或者用另一种表示法:

awk -v FS='\n' -v OFS='|' -v RS='' '{$1=$1} 1' file
输出:

one|two|three 一|二|三

请参阅:

使用字段分隔符将一列转换为一行:

awk '{$1=$1} 1' FS='\n' OFS='|' RS='' file
或者用另一种表示法:

awk -v FS='\n' -v OFS='|' -v RS='' '{$1=$1} 1' file
输出:

one|two|three 一|二|三

请参阅:

awk
解决方案非常有效。以下是
tr+sed
解决方案:

tr'\n''sed's/\\\\\\;$/'
1|2|3

awk
解决方案非常有效。以下是
tr+sed
解决方案:

tr'\n''sed's/\\\\\\;$/'
1|2|3
只需将其展平:

gawk/mawk 'BEGIN { FS = ORS; RS = "^[\n]*$"; OFS = "|" 
                
             } NF && ( $NF ? NF=NF : —-NF )' 
ascii
|
=八进制
\174
=十六进制
0x7C
--NF
的原因是,输入常常包含一个尾随的新行,这使得字段计数1过多,并导致

1|2|3|
1 \351 2 \351 . . .
NF=NF
--NF
都是与$1=$1类似的概念。空输入,无论是否存在尾随新行,都将导致不打印任何内容

在OFS的
spot,您可以使用您喜欢的任何字符串组合对其进行分隔,而不必受行为不一致的
tr
的约束。例如:

gtr '\012' '高'   # UTF8 高 = \351\253\230 = xE9 xAB x98 
bsd tr
上,
\n
将被unicode替换
1高2.高3.高
,但如果您使用的是
gnutr
,它将只保留unicode的前导字节,并导致

1|2|3|
1 \351 2 \351 . . .
对于unicode等价类,bsd tr在
gtr'时按预期工作[=高=]' '\v'
会导致

gtr: ?\230: equivalence class operand must be a single character
如果您尝试使用任意非ASCII字节的equiv类,bsd tr将不会执行任何操作,而gnu tr将乐意执行此操作,即使这意味着直接分割符合UTF8的字符:

g3bn 77138 | (g)tr '[=\224=]' '\v'

bsd-tr : 77138=Koyote 코요태 KYT✜ 高耀太
gnu-tr : 77138=Koyote ?
                       ?
                         태 KYT✜ 高耀太
把它展平:

gawk/mawk 'BEGIN { FS = ORS; RS = "^[\n]*$"; OFS = "|" 
                
             } NF && ( $NF ? NF=NF : —-NF )' 
ascii
|
=八进制
\174
=十六进制
0x7C
--NF
的原因是,输入通常包含一个尾随的新行,这使得字段计数1过多,并导致

1|2|3|
1 \351 2 \351 . . .
NF=NF
--NF
都是与$1=$1类似的概念。空输入,无论尾随的新行是否存在,都将导致不打印任何内容

在OFS的
位置,您可以使用任何您喜欢的字符串组合对其进行分隔,而不是受行为不一致的
tr
约束。例如:

gtr '\012' '高'   # UTF8 高 = \351\253\230 = xE9 xAB x98 
bsd tr
上,
\n
将被unicode替换
1高2.高3.高
,但如果您使用的是
gnutr
,它将只保留unicode的前导字节,并导致

1|2|3|
1 \351 2 \351 . . .
对于unicode等价类,bsd tr在
gtr'时按预期工作[=高=]' '\v'
会导致

gtr: ?\230: equivalence class operand must be a single character
如果您尝试使用任意非ASCII字节的equiv类,bsd tr将不会执行任何操作,而gnu tr将乐意执行此操作,即使这意味着直接分割符合UTF8的字符:

g3bn 77138 | (g)tr '[=\224=]' '\v'

bsd-tr : 77138=Koyote 코요태 KYT✜ 高耀太
gnu-tr : 77138=Koyote ?
                       ?
                         태 KYT✜ 高耀太

我会按照下面的方法来做,使用GNU
AWK
,让
test.txt
内容

one
two
three
然后

输出

one|two|three
说明:如果是第一行打印,则行内容不带尾随换行符,否则
后面是行内容不带尾随换行符。请注意,我假设
test.txt
没有尾随换行符,如果不是这种情况,请在应用此解决方案之前对其进行测试


(在gawk 5.0.1中测试)

我会按照下面的方法做,使用GNU
AWK
,让
test.txt
内容

one
two
three
然后

输出

one|two|three
说明:如果是第一行打印,则行内容不带尾随换行符,否则
后面是行内容不带尾随换行符。请注意,我假设
test.txt
没有尾随换行符,如果不是这种情况,请在应用此解决方案之前对其进行测试


(在gawk 5.0.1中进行了测试)

您也可以使用
awk

awk '{ORS = (NR%3 ? "|" : RS)} 1' file
one|two|three
%
是模运算符,
NR%3?”|“:RS
是三元表达式

  • 请参见Ed Morton的解释:

    • 您也可以使用
      awk
      来尝试:

      awk '{ORS = (NR%3 ? "|" : RS)} 1' file
      one|two|three
      
      %
      是模运算符,
      NR%3?”|“:RS
      是三元表达式

      • 请参见Ed Morton的解释:

      使用GNU
      sed
      ,您可以传递
      -z
      选项以匹配换行符,因此您只需替换每个换行符,但最后一个换行符位于字符串末尾:

      sed-z's/\n\(.\)/\1/g'test.txt
      perl-0pe的/\n(?!\z)/|/g'test.txt
      perl-pe's/\n/|/g if!eof'test.txt
      

      详情:

      • s
        -替换命令
      • \n\(.\)
        -一个LF字符后跟捕获到组1中的任何一个字符(因此字符串末尾的
        \n
        不会匹配)
      • |\1
        -a
        |
        字符和捕获的字符
      • g
        -所有事件
      第一个
      perl
      命令匹配字符串(
      (?!\z)
      )末尾以外的任何LF char(
      ),然后将整个文件转换为单个字符串输入