简体   繁体   中英

Awk: how to print the field separator with your columns (field separator also a regular expression)

I have a file that looks like

3 5 t27s60  
4 8 s30s40
2 2 t80t10
6 4 s80t10

And I want to produce a file like

3 5 t27 s60  
4 8 s30 s40
2 2 t80 t10
6 4 s80 t10

So I would specify the field separator as s or t, but I want to keep these characters in the output.

AFAIK it is not possible to obtain the exact field delimiter when FS has been set to a regular expresssion.

I would use sed for this use case:

sed 's/...$/ &/' file

The s command substitutes the last 3 characters in a line ... before the end $ by a space and itself & .


If counting characters from the end does not work because the number of characters after the delimiter is not fixed, you can use the following sed command:

sed -r 's/(s|t)([^st]+)$/ \1\2/' file

I'm searching for s or t using (s|t) followed by 1 or more characters until the which are neither s or t .

A quick awk one-liner:

awk '{gsub(/[st]/," &",$0)}1' input.txt

outputs:

3 5  t27 s60  
4 8  s30 s40
2 2  t80 t10
6 4  s80 t10

Here, we use the special meaning of & in the gsub command: it stands for the machted expression. Hence, gsub(/[st]/," &",$0) prepends a blank before each "s" or "t"

If repeated blanks are a problem:

awk '{gsub(/[st]/," &",$0);gsub(/[ ]+/," ",$0)}1' input.txt

which gives:

3 5 t27 s60 
4 8 s30 s40
2 2 t80 t10
6 4 s80 t10

Or perl, add a space before an "s" or "t", if the previous character is not whitespace:

perl -pe 's/(?<=\S)([st])/ $1/g' file

The equivalent awk is

awk '{print gensub(/([^[:blank:]])([st])/, "\\\1 \\\2", "g")}' file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM