Skip to main content

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
Asked
Modified 1 month ago
Viewed 121 times
-2

In the below shell script I want to extract the fields of a string delimited by | character. But unfortunately I'm facing issue if there exists pipe command | in the string, because of which I'm not able to extract the required fields

#!/bin/bash

_a=""
b=""
_c=""
_d=""

test_def1="abc|pidof abc|0|0"
if [[ "$test_def1" == *"|"*"|"*"|"* ]]; then
        echo "valid"
        IFS='|' read -r _a b _c _d <<< "${test_def1}"
        readarray -t _process_ids < <(ssh -o StrictHostKeyChecking=no -l root 192.168.1.50 "$b")
else
        echo "invalid"
fi

test_def2="abc|ps -a | awk "/abc/ { print \$1 }"|0|0"
if [[ "$test_def2" == *"|"*"|"*"|"* ]]; then
        echo "valid"
        IFS='|' read -r _a b _c _d <<< "${test_def2}"
        # expecting b to contain ps -a | awk "/abc/ { print \$1 }"
        readarray -t _process_ids < <(ssh -o StrictHostKeyChecking=no -l root 192.168.1.50 "$b")
else
        echo "invalid"
fi

Current output

valid
pidof abc
main.bash: line 18: {: command not found
invalid

Expected output

valid
pidof abc
valid
ps -a | awk "/abc/ { print \$1 }"
8
  • you may want to double-check the line test_def2="abc|ps -a | awk "/abc/ { print \$1 }"|0|0", and especially how it looks like with the syntax highlighting above.
    ilkkachu
    –  ilkkachu
    2025-09-04 07:14:43 +00:00
    Commented Sep 4 at 7:14
  • @ilkkachu I know the second field command ps -a | awk "/abc/ { print \$1 }" syntax messing up with the pattern that I'm trying to match. Even if I make test_def2 as abc|ps -a | awk '/abc/ { print \$1 }'|0|0, it's matching b with ps -a instead of ps -a | awk '/abc/ { print \$1 }'
    Harry
    –  Harry
    2025-09-04 07:17:42 +00:00
    Commented Sep 4 at 7:17
  • 4
    Would you consider telling us what you're trying to achieve rather than asking us to figure out why what you're doing is failing?
    tink
    –  tink
    2025-09-04 07:34:49 +00:00
    Commented Sep 4 at 7:34
  • 9
    IMO the root cause of the problems you're running into is that you keep trying to use bash for text processing. Bash, or any shell, is probably the worst possible choice for doing any kind of text or data processing. It's absolutely terrible at it and some of its problems are impossible to work around. The rest are merely difficult to work around and doing so results in unreadable code. Learn perl. or awk. or python. Or any other language. Use bash for what it's good at: co-ordinating the execution of other programs to do the text processing (or other work).
    cas
    –  cas
    2025-09-04 08:54:03 +00:00
    Commented Sep 4 at 8:54
  • 3
    No matter what language you use, you need some way to distinguish the field delimiter if it can also be a constituent. In CSV files this is done using quoting. If only one of the fields of your file can contain | characters, you can solve the problem by extracting fixed fields from the beginning and end, and then everything in between is the more general field.
    Barmar
    –  Barmar
    2025-09-04 15:40:23 +00:00
    Commented Sep 4 at 15:40

1 Answer 1

1

It's not clear why you're trying to do what you show, nor whether or not there are any other use cases to be considered, but this would produce the output I think you want from the relevant code sections given the input you provided:

$ re='^[^|]*[|](.*)([|][^|]*){2}$'

$ test_def1='abc|pidof abc|0|0'
$ if [[ "$test_def1" =~ $re ]]; then echo "${BASH_REMATCH[1]}"; fi
pidof abc

$ test_def2='abc|ps -a | awk "/abc/ { print \$1 }"|0|0'
$ if [[ "$test_def2" =~ $re ]]; then echo "${BASH_REMATCH[1]}"; fi
ps -a | awk "/abc/ { print \$1 }"

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.