0

I have input like this ,i need move the line after *_job to the end of the *_job line, if it is job_type and print the entire file. IF the next line is not job_type just print them.

i able to print only line having *_job by SED,but not the entire file ,can some one help me ..

 sed -i -n '/.*_job: .*/{h}; /job_type.*/{H;x;s/\n/ /;p}'

Input.

update_job: YUHG_GHT_FGT_BOX
job_type: box
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXXXXX
insert_job: TYYUH_JYUH_BOX
job_type: cmd
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXX
insert_job: TYU_hju_poonj
job_type: CMD
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXX

insert_job: YU_opoj_BOX job_type: BOX
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XX

insert_job: YU_opoj_BOX
job_type: BOX
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XX

Expected O/P:-

update_job: YUHG_GHT_FGT_BOX job_type: box
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXXXXX
insert_job: TYYUH_JYUH_BOX job_type: cmd
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXX
insert_job: TYU_hju_poonj job_type: CMD
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXX

insert_job: YU_opoj_BOX job_type: BOX
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XX

insert_job: YU_opoj_BOX job_type: BOX
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XX
5
  • 1
    You say i need move the line after *_job to the end of the *_job line, if it is job_type but you didn't say what to do if the line after _job is not job_type nor did you include any examples of that case in your sample input/output to show how to handle it. Please edit your question to state and show your requirements for that case. Also, if you can have multiple contiguous _job lines before a job_type line then state how that should be handled and include it in your example too.
    – Ed Morton
    Commented Feb 4, 2022 at 19:22
  • 1
    Edited the question and input/op ,Thanks @Ed Morton
    – Renga
    Commented Feb 5, 2022 at 13:53
  • Oh, so the only time a _job line isnt followed by a job_type line is when _job is already part of the job_type line?
    – Ed Morton
    Commented Feb 5, 2022 at 14:01
  • It Might Repeat or may not,its un predictable @Ed Morton
    – Renga
    Commented Feb 5, 2022 at 14:09
  • 1
    If it might repeat then you should include at least one case where it does repeat in your example so you get a solution that does whatever it is you want to do if/when it does repeat. It's always easy to write code to handle sunny day cases and much harder to write code to robustly handle rainy day cases so you should always include the worst possible rainy day cases in your sample input/output, not just the sunny-day.
    – Ed Morton
    Commented Feb 5, 2022 at 14:11

5 Answers 5

2

You can do:

sed '/_job/{N;/\
job_type/s/\
/ /;}' infile

if a line is contain _job then read the Next line and append to the pattern space and remove the embedded \newline character (which we used actual newline here by breaking the line down with backslash \ then actual newline) if that line is starting with job_type.

3
  • suppose the _job and job_type in the same line , in this case its altering the next line not ignoring them..
    – Renga
    Commented Feb 4, 2022 at 11:43
  • 1
    please ignore i added \n and working "sed '/_job:/{N;/\njob_type:/s/\n/ /;}' "
    – Renga
    Commented Feb 4, 2022 at 11:46
  • @Renga fixed, thanks Commented Feb 4, 2022 at 13:01
1

Using perl to read the file in paragraph mode (-00) and perl's /m regex modifier so that we can process multi-line strings with a single regex:

$ perl -00 -p -e 's/(_job:.*?)\n(job_type:)/$1 $2/mg' input.txt
update_job: YUHG_GHT_FGT_BOX job_type: box
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXXXXX
insert_job: TYYUH_JYUH_BOX job_type: cmd
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXX
insert_job: TYU_hju_poonj job_type: CMD
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXX

insert_job: YU_opoj_BOX job_type: BOX
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XX

insert_job: YU_opoj_BOX job_type: BOX
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XX

This effectively replaces the newline between a line containing _job: and any immediately following line which starts with job_type, with a single space. Lines which don't match that exact criterion are left as-is, unchanged.

It uses two capture groups, (_job:.*?) and (job_type:), and perl's non-greedy regex quantifier ? so that the first capture group only matches from _job: to everything before the first newline after _job: (i.e. the remainder of the line).

BTW, if there's any chance that there might be trailing whitespace at the end of the _job: line and/or any leading whitespace before the jobtype: line, change \n in the regex to \s*\n\s*

As with sed, you can use the -i option if you want it to modify the original file instead of printing to stdout.

0

Simple in Perl:

perl -pi -e 'tr/\n/ / if /_job/' -- file
  • -p reads the input line by line and prints each line after processing
  • -i changes the file in place
  • tr/\n/ / replaces the newline with a space
  • if /_job/ only runs the command if the condition is true, i.e. if the line contains _job.
2
  • it is mentioned that the next line should only merge if it was job_type Commented Feb 4, 2022 at 11:02
  • Then the sample input is incomplete :-)
    – choroba
    Commented Feb 4, 2022 at 11:28
0

Given your posted sample input/output it sounds like you want to do the following, using any awk in any shell on every Unix box:

$ awk '/_job/ && !/job_type/{j=$0 OFS; next} {print j $0; j=""}' file
update_job: YUHG_GHT_FGT_BOX job_type: box
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXXXXX
insert_job: TYYUH_JYUH_BOX job_type: cmd
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXX
insert_job: TYU_hju_poonj job_type: CMD
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XXX

insert_job: YU_opoj_BOX job_type: BOX
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XX

insert_job: YU_opoj_BOX job_type: BOX
condition : s(XXXYYUYBJHBJb) &
svcdesk_desc: XX
0

With ed:

printf '%s\n' 'g/^job_type:/ s/^/ /\' '-1,.j' ',p' 'Q' | ed -s file

The editing script:

g/^job_type:/ s/^/ /\
-1,.j
,p
Q

This applies a substitution command (s) and a join command (j) to all lines in the editing buffer that starts with the literal string job_type:. The substitution inserts a single space at the start of the line and the join command joins the affected line with the previous line in the buffer.

The trailing p and Q commands prints the modified buffer to the terminal and quits. You may change these to wq to write the result back to the original file if you wish to make an in-place edit.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .