Li Po
Li Po

Reputation: 43

How to print contents of column fields that have strings composed of "n" character/s using bash?

Say I have a file which contains:

22  30  31  3a  31  32  3a  32          " 0 9 : 1 2 : 2
30  32  30  20  32  32  3a  31          1 2 7   2 2 : 1

And, I want to print only the column fields that have string composed of 1 character. I want the output to be like this:

" 0 9 : 1 2 : 2
1 2 7   2 2 : 1

Then, I want to print only those strings that are composed of two characters, the output should be:

22  30  31  3a  31  32  3a  32
30  32  30  20  32  32  3a  31 

I am a beginner and I really don't know how to do this. Thanks for your help!

Upvotes: 0

Views: 263

Answers (3)

RavinderSingh13
RavinderSingh13

Reputation: 133650

Could you please try following, I am trying it in a different way for provided samples. Written and tested with provided samples only.

For getting values before BULK SPACE try:

awk '
{
  line=$0
  while(match($0,/[[:space:]]+/)){
    arr=arr>RLENGTH?arr:RLENGTH
    start[arr]+=RSTART+prev_start
    prev_start=RSTART
    $0=substr($0,RSTART+RLENGTH)
  }
  var=substr(line,1,start[arr]-1)
  sub(/ +$/,"",var)
  print var
  delete start
  var=arr=""
}
'  Input_file

Output will be as follows.

22  30  31  3a  31  32  3a  32
30  32  30  20  32  32  3a  31


For getting values after BULK SPACE try:

awk '
{
  line=$0
  while(match($0,/[[:space:]]+/)){
    arr=arr>RLENGTH?arr:RLENGTH
    start[arr]+=RSTART+prev_start
    prev_start=RSTART
    $0=substr($0,RSTART+RLENGTH)
  }
  var=substr(line,start[arr])
  sub(/^ +/,"",var)
  print var
  delete start
  var=arr=""
}
'  Input_file

Output will be as follows:

" 0 9 : 1 2 : 2
1 2 7   2 2 : 1

Upvotes: 3

Shawn
Shawn

Reputation: 52549

Assuming all the columns are tab-separated (So you can have a space as a column value like the second line of your sample), easy to do with a perl one-liner:

$ perl -F"\t" -lane 'BEGIN { $, = "\t" } print grep { /^.$/ } @F' foo.txt
"       0       9       :       1       2       :       2
1       2       7               2       2       :       1
$ perl -F"\t" -lane 'BEGIN { $, = "\t" } print grep { /^..$/ } @F' foo.txt
22      30      31      3a      31      32      3a      32
30      32      30      20      32      32      3a      31

Upvotes: 0

dibery
dibery

Reputation: 3470

You can try

awk '{for(i=1;i<=NF;++i)if(length($i)==1)printf("%s ", $i);print("")}'

For each field, check the length and print it if it's desired. You may pass the -F option to awk if it's not separated by blanks.

The awk script is expanded as:

for( i = 1; i <= NF; ++i )
  if( length( $i ) == 1 )
    printf( "%s ", $i );
print( "" );

The print outside loop is to print a newline after each input line.

Upvotes: 2

Related Questions