Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Suppose I have a file in which I'd like to simultaneously print different awk commands following the first column instuctions, without messing up the original file (as it would happen with two separate prints):

File:

End 1st 2nd 3rd
Fin 1st 2nd 3rd

I'd like to combine the following commands into a one-liner:

awk '$1 ~ /^E/ {print $2}'
awk '$1 ~ /^F/ {print $3}'

To obtain the following output:

End 1st
Fin 2nd

EDIT What I meant by saying "messing up the original file":

File 1:

E1   NAME1 LASTNAME1
FA   22   1992         #age, year
FC   UK   London       #country, city
FJ   IT   HP           #job, company
E2   NAME2 LASTNAME2
FA   25   1989        
FC   CH   Geneva      
FJ   CS   SIB    

Now, if I run two separate awk prints, I won't be able to match the information in File 3 with the names of File 2 (especially if the number of ^F fields are not of the same number):

awk '$1 ~ /^E/ {print $2}' File 1 > File 2

Output (File 2):

NAME1
NAME2

awk '$1 ~ /^F/ {print $3}' File 1 > File 3

Output (File 3):

1992        
London       
HP           
1989        
Geneva      
SIB  

But, If I join them (as suggested in the answers) I'll be able to have something like this:

Expected output:

NAME1
1992        
London       
HP  
NAME2
1989        
Geneva      
SIB  
share|improve this question
2  
In what way does two separate prints "mess up" the original file? What's wrong with simply doing awk '$1 ~ /^E/ {print $1,$2}; $1 ~ /^F/ {print $1,$3}'? –  steeldriver Jul 25 at 13:53
    
I meant, if I had multiple ^F lines (let's say "descrption lines") belonging to a same ^E line (let's say, an "identifier"), and I performed two separate awk, I would end up with two well written files, but I wouldn't be able to distinguish the ^F lines belonging to a given ^E line. –  Dovah Jul 25 at 14:02
    
Can you give a minimal example? The example in your question does not seem to be sufficient to illustrate what you want. –  steeldriver Jul 25 at 14:07
1  
I think I know what he means: If he does the first awk commando, he'll just get End lines. The following Fin lines, which are related to the End lines, are excluded in this search and therefor the correlation between both types is lost. So he needs an awk command that prints them in order. –  polym Jul 25 at 14:17
    
Exact, @polym. That's what I meant. However, I joined an edit to my question, I hope it's a bit more clear. –  Dovah Jul 25 at 14:25

4 Answers 4

up vote 5 down vote accepted
awk '$1 ~ /^E|^F/ {if ($1 == "End") print $1" "$2; if ($1 == "Fin") print $1" "$3}'

or

awk '/^End/{print $1" "$2}/^Fin/{print $1" "$3}'

(thanks to Jidder)

Should work.

share|improve this answer
    
A lot of that code is redundant, if $1="End" then $1 must start with E so the first argument is not needed. This could be reduced to awk '/^End/{print $1" "$2}/^Fin/{print $1" "$3}' whilst doing the exact same comparisons –  Jidder Jul 25 at 15:03

Try:

awk '$1 ~ /^E/ {print $1,$2;next} $1 ~ /^F/ {print $1,$3}' file
share|improve this answer
    
What does the next do? –  polym Jul 25 at 13:59
    
@polym I guess it's effectively a short-circuit logic operator (no need to ~ /^F/ if you've already matched /^E/) –  steeldriver Jul 25 at 14:06
    
@steeldriver Oh so like a continue in C? Ok that makes sense. –  polym Jul 25 at 14:14
    
From the man page of awk: next # skip remaining patterns on this input line –  groxxda Jul 25 at 14:16
1  
@Jidder they're not exactly equivalent - with the default FS, awk will trim leading whitespace so $1 may be equal to End yet $0 equals ___End for example [EDIT: stupid comment markdown won't let me post leading whitepsace in a code sequence]. –  steeldriver Jul 25 at 15:12

This should work

awk '/^F/{$2=$3}NF=(NF-2)' file

If you want to match E as well(if there are other things in the file)

awk 'a=/^F/{$2=$3}{x=/^E/}(x||a)&&NF=(NF-2)' file
share|improve this answer

For Expected output,

awk '/^E/{$0=$2} /^F/{$0=$3}1' file

If you want to print first field as well,

awk '/^E/{$0=$1 FS $2} /^F/{$0=$1 FS $3}1' file
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.