开发者

How to position part of the line after pattern (including it) after 80th character?

开发者 https://www.devze.com 2023-02-13 20:06 出处:网络
I know that question sounds a little odd but i will try to explain it more. I have a file params that looks like this:

I know that question sounds a little odd but i will try to explain it more.

I have a file params that looks like this:

3       p       1 1.732051 0 1.9628$/x2r_a/  
4       p       1 1.732051 0 -1.9628$/x2r_a/  
5       p       -1 1.732051 0 1.9628$/x2r_a/  
6       p       -1 1.732051 0 -1.9628$/x2r_a/  

What i want to achieve is to move everything after (and with) $ to the right, ie 80th 'place' of a line:

3       p       1 1.732051 0 1.9628                                   $/x2r_a/  
4       p       1 1.732051 0 -1.9628                                  $/x2r_a/  
5       p       -1 1.732051 0 1.9628                                  $/x2r_a/  
6       p       -1 1.732051 0 -1.9628                                 $/x2r_a/

We don't know the exact length of the string before the $ sign. Also the space between must be filled with spaces and nothing more.

As always i need to do it in bash 2.05 probably with sed, awk or sth like that.

UPDATE

I wasn't specific about how file look like so here's more:

c ------------------
c Something stupid
c ------------------
c there is a number: 9$/ar_numb/
c a 开发者_开发知识库line that looks
1       px      0.9814$/r_a/
2       px      -0.9814$/r_a/
3       p       1 1.732051 0 1.9628$/x2r_a/
4       p       1 1.732051 0 -1.9628$/x2r_a/
5       p       -1 1.732051 0 1.9628$/x2r_a/
6       p       -1 1.732051 0 -1.9628$/x2r_a/
c
c dirty line
7       cz      0.9347$/x05d_a/
c very dirty
41      p       0$/A_Nel/!jl
        1$/B_Nel/!jl
        0$/C_Nel/!jl
        0$/D_Nel/!jl
        $bad element
42      p       1.723051$/A_NEel/!jl
        1$/B_NEel/!jl
        0$/C_NEel/!jl
        0$/D_NEel/!jl
        $kokode nanika kaite kudasai

I will not post changed version becouse it would be too long. I want $[string] parts to be moved to the right, but those lines without $ thing will remain as they are.


Based on kojiro's answer to include the new requirements

awk -F'$' '/\$/{printf("%-79s$%s\n", $1, $2);next}1' ./params

Proof of Concept

$ awk -F'$' '/\$/{printf("%-79s$%s\n", $1, $2);next}1' ./params
c ------------------
c Something stupid
c ------------------
c there is a number: 9                                                         $/ar_numb/
c a line that looks
1       px      0.9814                                                         $/r_a/
2       px      -0.9814                                                        $/r_a/
3       p       1 1.732051 0 1.9628                                            $/x2r_a/
4       p       1 1.732051 0 -1.9628                                           $/x2r_a/
5       p       -1 1.732051 0 1.9628                                           $/x2r_a/
6       p       -1 1.732051 0 -1.9628                                          $/x2r_a/
c
c dirty line
7       cz      0.9347                                                         $/x05d_a/
c very dirty
41      p       0                                                              $/A_Nel/!jl
        1                                                                      $/B_Nel/!jl
        0                                                                      $/C_Nel/!jl
        0                                                                      $/D_Nel/!jl
                                                                               $bad element
42      p       1.723051                                                       $/A_NEel/!jl
        1                                                                      $/B_NEel/!jl
        0                                                                      $/C_NEel/!jl
        0                                                                      $/D_NEel/!jl
                                                                               $kokode nanika kaite kudasai


awk -F'$' '{ printf("%-80s$%s\n", $1, $2) }' params


This might work for you:

# sed '\|\(.*\)\($/.*\)|{h;x;s//\2/;x;s//\1/;:a;s/^.\{1,78\}$/ &/;ta;s/^\( *\)\(.*\)/\2\1/;G;s/\n//}' params
c ------------------
c Something stupid
c ------------------
c there is a number: 9                                                         $/ar_numb/
c a line that looks
1       px      0.9814                                                         $/r_a/
2       px      -0.9814                                                        $/r_a/
3       p       1 1.732051 0 1.9628                                            $/x2r_a/
4       p       1 1.732051 0 -1.9628                                           $/x2r_a/
5       p       -1 1.732051 0 1.9628                                           $/x2r_a/
6       p       -1 1.732051 0 -1.9628                                          $/x2r_a/
c
c dirty line
7       cz      0.9347                                                         $/x05d_a/
c very dirty
41      p       0                                                              $/A_Nel/!jl
1                                                                              $/B_Nel/!jl
0                                                                              $/C_Nel/!jl
0                                                                              $/D_Nel/!jl
        $bad element
42      p       1.723051                                                       $/A_NEel/!jl
1                                                                              $/B_NEel/!jl
0                                                                              $/C_NEel/!jl
0                                                                              $/D_NEel/!jl
        $kokode nanika kaite kudasai
# printf "%.1s" {1..90}
123456789111111111122222222223333333333444444444455555555556666666666777777777788888888889# 

Explanation:

  1. Only edit those lines that contain $/...
  2. Copy the line into the hold space (HS).
  3. Swap to the HS and delete everything but the string $/....
  4. Swap back to the pattern space (PS) and do the reverse i.e. delete $/...
  5. Indent the PS with spaces to the 79th column
  6. Swap the spaces at the front of the PS with the non-spaces.
  7. Append the HS to the PS i.e. add the $/... string to the end of the line.
  8. Delete the embedded newline caused by the G command.

Alternatively:

sed '\|\(.*\)\($/.*\)|!{s/.*/printf "%s\n" "&"/;b};s//printf "%-79s%s\n" "\1" "\2"/' params | sh

Or with GNU sed:

sed '\|\(.*\)\($/.*\)|{s//printf "%-79s%s" "\1" "\2"/e}' params
0

精彩评论

暂无评论...
验证码 换一张
取 消