0

cat file1.txt | awk -F '{print $1 "|~|" $2 "|~|" $3}' > file2.txt

I am using above command to filter first three columns from file1 and put into file.

But only getting the column names and not the column data.

How to do that?

|~| - is the delimiter.

file1.txt has values as :

 a|~|b|~|c|~|d|~|e
 1|~|2|~|3|~|4|~|5
 11|~|22|~|33|~|44|~|55
 111|~|222|~|333|~|444|~|555

my expedted output is :

 a|~|b|~|c
 1|~|2|~|3
 11|~|22|~|33
 111|~|222|~|333
Inian
  • 80,270
  • 14
  • 142
  • 161
Aviator
  • 543
  • 1
  • 4
  • 10

4 Answers4

5

With your shown samples, please try following awk code. You need to set field separator to |~| and remove starting space from lines, then print the lines.

awk -F'\\|~\\|' -v OFS='|~|' '{sub(/^[[:blank:]]+/,"");print $1,$2,$3}' Input_file

In case you want to keep spaces(which was in initial post before edit) then try following:

awk -F'\\|~\\|' -v OFS='|~|' '{print $1,$2,$3}' Input_file

NOTE: Had a chat with user in room and got to know why this code was not working for user because of gunzip -c file was being used wrongly, its output was being saved into a variable on which user was running awk program, so correcting that command generated right file and awk program ran fine on it. Adding this as a reference for future readers.

RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • 2
    Yep, you got it! I hate the `"|~|"` ones -- whoever thought that up as a field separator -- should be shot... – David C. Rankin Jul 16 '21 at 09:47
  • But I am only getting the column names, I want the column data as well. – Aviator Jul 16 '21 at 11:40
  • 1
    @Aviator, With your shown samples this code works. Is your actual file is same as shown samples? – RavinderSingh13 Jul 16 '21 at 11:42
  • Its not the same file, but its in the same format! – Aviator Jul 16 '21 at 11:43
  • @Aviator, yeah, if its same format it should work IMHO. What is not working could you please elaborate on this one? – RavinderSingh13 Jul 16 '21 at 11:45
  • What is not working ? -- Only the column names getting printed. that means i am getting only : a|~|b|~|c – Aviator Jul 16 '21 at 11:50
  • But I want the column data also. – Aviator Jul 16 '21 at 11:50
  • @Aviator, with your shown samples it gives columns data. Post here 1 line of sample input and expected output to make it clear. – RavinderSingh13 Jul 16 '21 at 11:51
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234970/discussion-between-aviator-and-ravindersingh13). – Aviator Jul 16 '21 at 11:52
  • @Aviator, Hi, could you please update your question(by not changing it drastically) where you could mention 2 points,1- I believe you needed to remove starting tabs/spaces in each line(which is lost in question's editing), 2- your gunzip issue by which is your file is getting generated. if you edit your question this will make it different from your previous question(which this question actually is), else this may get close as duplicate. Kindly do make changes to this question, cheers and happy learning. – RavinderSingh13 Jul 17 '21 at 02:26
  • @Aviator, Hi, could you please update your question(by not changing it drastically) where you could mention 2 points,1- I believe you needed to remove starting tabs/spaces in each line(which is lost in question's editing), 2- your gunzip issue by which is your file is getting generated. if you edit your question this will make it different from your previous question(which this question actually is), else this may get close as duplicate. Kindly do make changes to this question, cheers and happy learning. – RavinderSingh13 Jul 24 '21 at 16:21
3

One approach would be:

awk -v FS="," -v OFS="|~|" '{gsub(/[|][~][|]/,","); sub(/^\s*/,"");  print $1,$2,$3}' file1.txt

The approach simply replaces all "|~|" with a "," setting the output file separator to "|~|". All leading whitespace is trimmed with sub().

Example Use/Output

With your data in file1.txt, you would have:

$ awk -v FS="," -v OFS="|~|" '{gsub(/[|][~][|]/,","); sub(/^\s*/,"");  print $1,$2,$3}' file1.txt
a|~|b|~|c
1|~|2|~|3
11|~|22|~|33
111|~|222|~|333

Let me know if this is what you intended. You can simply redirect, e.g. > file2.txt to write to the second file.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
2

For such cases, my bash+awk script rcut comes in handy:

rcut -Fd'|~|' -f-3 ip.txt

The -F option enables fixed string input delimiter (which is given using the -d option). And by default, the output field separator will also be same as -d when -F is active. -f-3 is similar to cut syntax to specify first three fields.



For better speed, use hck command:

hck -Ld'|~|' -D'|~|' -f-3 ip.txt

Here, -L enables literal field separator and -D specifies output field separator.

Another benefit is that hck supports -z option to automatically handle common compressed formats based on filename extension (adding this since OP had an issue with compressed input).

Sundeep
  • 23,246
  • 2
  • 28
  • 103
1

Another way:

sed 's/|~|/\t/g' file1.txt | awk '{print $1"|~|"$2"|~|"$3}' > file2.txt

First replace the |~| delimiter, and use the default awk separator, then print columns what you need.

Victor Lee
  • 2,467
  • 3
  • 19
  • 37
  • 1
    yes, I delete that flag, and if first use `sed` to replace some character, it will cover the space case auto by `awk` I think. – Victor Lee Jul 16 '21 at 09:57
  • But this is only returning the column names i want the column data as well. – Aviator Jul 16 '21 at 11:34
  • @Aviator could you show your running screenshot? It works for me, this command will return the all rows with define columns. – Victor Lee Jul 16 '21 at 11:40
  • how can I put screenshot(image) here ? – Aviator Jul 16 '21 at 11:43
  • You could update your question, but suggest paste it to comment me. – Victor Lee Jul 16 '21 at 11:44
  • 1
    You never need sed when you're using awk and that would fail if any of the fields in the input contained blanks or tabs. – Ed Morton Jul 16 '21 at 12:28
  • Thanks point that, but I have test that and it works, the default `awk` separator will handle the blanks or tabs. Check it from "https://stackoverflow.com/questions/30405694/default-field-separator-for-awk". – Victor Lee Jul 16 '21 at 12:53