2

How can remove everything in a pipe delimited file after the second-to-last pipe? Like for the line

David|3456|ACCOUNT|MALFUNCTION|CANON|456

the result should be

David|3456|ACCOUNT|MALFUNCTION
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Satya
  • 21
  • 2

4 Answers4

2

Replace |(string without pipe)|(string without pipe) at the end of each line:

sed 's/|[^|]*|[^|]*$//' inputfile
Walter A
  • 19,067
  • 2
  • 23
  • 43
1

Using awk, something like

awk -F'|' 'BEGIN{OFS="|"}{NF=NF-2; print}' inputfile
David|3456|ACCOUNT|MALFUNCTION

(or) use cut if you know the number of columns in total, i,e 6 -> 4

cut -d'|' -f -4 inputfile
David|3456|ACCOUNT|MALFUNCTION
Inian
  • 80,270
  • 14
  • 142
  • 161
  • not working. Printing entire file as it is. is there anything I am missing here? tried as awk -F'|' 'BEGIN{OFS="|"}{NF=NF-2; print}' /home/user/file.txt – Satya Dec 14 '16 at 18:59
  • Are you on a Windows machine under `cygwin` maybe? Which Linux and which `awk` version are you using? Can you output `awk --version` ? and `which awk` – Inian Dec 14 '16 at 19:03
  • @Satya: can you do `dos2unix < /home/user/file.txt`, before running the `awk` command? – Inian Dec 14 '16 at 19:06
  • The `one-true-awk` (AKA `nawk`) does not reevaluate the record until an assignment is made to one of its fields. The following wil work as intended: `{NF-=2;$1=$1}1` – kdhp Dec 15 '16 at 01:42
0

The command I would use is

cat input.txt | sed -r 's/(.*)\|.*/\1/' > output.txt
Jake
  • 338
  • 1
  • 6
0

A pure Bash solution:

while IFS= read -r line || [[ -n $line ]] ; do
    printf '%s\n' "${line%|*|*}"
done <inputfile

See Reading input files by line using read command in shell scripting skips last line (particularly the answer by Jahid) for details of how the while loop works.

See pattern matching in Bash for information about ${line%|*|*}.

Community
  • 1
  • 1
pjh
  • 6,388
  • 2
  • 16
  • 17