Bash Separate Parameters with Specific Delimiter

bash separate parameters with specific delimiter

How about

somecommand () {
printf '"%s"\n' "$@" | paste -s -d :
}

Use printf to add the quotes and print every entry on a separate line, then use paste with the -s ("serial") option and a colon as the delimiter.

Can be called like this:

$ somecommand "this is" "a" test
"this is":"a":"test"

How do I split a string on a delimiter in Bash?

You can set the internal field separator (IFS) variable, and then let it parse into an array. When this happens in a command, then the assignment to IFS only takes place to that single command's environment (to read ). It then parses the input according to the IFS variable value into an array, which we can then iterate over.

This example will parse one line of items separated by ;, pushing it into an array:

IFS=';' read -ra ADDR <<< "$IN"
for i in "${ADDR[@]}"; do
# process "$i"
done

This other example is for processing the whole content of $IN, each time one line of input separated by ;:

while IFS=';' read -ra ADDR; do
for i in "${ADDR[@]}"; do
# process "$i"
done
done <<< "$IN"

Parameter in bash script with multiple type of separators

#!/usr/bin/env bash

for i in ${*//[,;]/ }; do
echo $i
done
./x.sh "par1,par2;par3 par4"
par1
par2
par3
par4

$* is a special parameter that returns all arguments separated by the first character of the IFS special variable (a space by default).

${*//[,;]/ }; uses parameter expansion to replace all occurrences of pattern (characters , and ;) by a space.

Howto split a string on a multi-character delimiter in bash?

Since you're expecting newlines, you can simply replace all instances of mm in your string with a newline. In pure native bash:

in='emmbbmmaaddsb'
sep='mm'
printf '%s\n' "${in//$sep/$'\n'}"

If you wanted to do such a replacement on a longer input stream, you might be better off using awk, as bash's built-in string manipulation doesn't scale well to more than a few kilobytes of content. The gsub_literal shell function (backending into awk) given in BashFAQ #21 is applicable:

# Taken from http://mywiki.wooledge.org/BashFAQ/021

# usage: gsub_literal STR REP
# replaces all instances of STR with REP. reads from stdin and writes to stdout.
gsub_literal() {
# STR cannot be empty
[[ $1 ]] || return

# string manip needed to escape '\'s, so awk doesn't expand '\n' and such
awk -v str="${1//\\/\\\\}" -v rep="${2//\\/\\\\}" '
# get the length of the search string
BEGIN {
len = length(str);
}

{
# empty the output string
out = "";

# continue looping while the search string is in the line
while (i = index($0, str)) {
# append everything up to the search string, and the replacement string
out = out substr($0, 1, i-1) rep;

# remove everything up to and including the first instance of the
# search string from the line
$0 = substr($0, i + len);
}

# append whatever is left
out = out $0;

print out;
}
'
}

...used, in this context, as:

gsub_literal "mm" $'\n' <your-input-file.txt >your-output-file.txt

How to split one string into multiple variables in bash shell?

If your solution doesn't have to be general, i.e. only needs to work for strings like your example, you could do:

var1=$(echo $STR | cut -f1 -d-)
var2=$(echo $STR | cut -f2 -d-)

I chose cut here because you could simply extend the code for a few more variables...

In shell, split a portion of a string with dot as delimiter

First, note that you don't use $ when assigning to a parameter in the shell. Your first line should be just this:

AU_NAME=AU_MSM3-3.7-00.01.02.03

The $ is used to get the value of the parameter once assigned. And the bit after the $ can be an expression in curly braces with extra stuff besides just the name, allowing you to perform various operations on the value. For example, you can do something like this:

IFS=. read major minor micro build <<EOF
${AU_NAME##*-}
EOF

where the ##*- strips off everything from the beginning of the string through the last '-', leaving just "00.01.02.03", and the IFS (Internal Field Separator) parameter tells the shell where to break the string into fields.

In bash, zsh, and ksh93+, you can get that onto one line by shortening the here-document to a here-string:

IFS=. read major minor micro build <<<"${AU_NAME##*-}"

More generally, in those same shells, you can split into an arbitrarily-sized array instead of distinct variables:

IFS=. components=(${AU_NAME##*-})

(Though that syntax won't work in especially-ancient versions of ksh; in them you have to do this instead:

IFS=. set -A components ${AU_NAME##*-}

)

That gets you this equivalence (except in zsh, which by default numbers the elements 1-4 instead of 0-3):

major=${components[0]}
minor=${components[1]}
micro=${components[2]}
build=${components[3]}

How to split string into parameters in bash?

Throw your code into a file and then use shellcheck on it, and it will lead you to this page:

https://github.com/koalaman/shellcheck/wiki/SC2089

Quotes/backslashes will be treated literally. Use an array.

Do it this way, instead:

a=(-name "build.sh")
find . "${a[@]}"

Bash and IFS: string split to an array with specific separator based on a complete word-term

With bash parameter expansion and mapfile:

$ string='[Git status]-fn:-functionGitStatus'
$ mapfile -t array <<< "${string//-fn:-/$'\n'}"
$ echo "${array[@]}"
[Git status] functionGitStatus
$ echo "size: '${#array[@]}'"
2
$ for e in "${array[@]}"; do echo "'$e'"; done
'[Git status]'
'functionGitStatus'

Explanation: "${string//-fn:-/$'\n'}" is a bash parameter expansion with substitution: all (because // instead of /) -fn:- substrings in string are replaced by $'\n', that is, a newline (the $'...' syntax is documented in the QUOTING section of bash manual). <<< is the here-string redirection operator. It "feeds" the mapfilecommand with the result of the parameter expansion with substitution. mapfile -t array (also documented in the bash manual) stores its input in the bash array named array, one line per cell, removing the trailing newline character (-t option).

In bash, how do I join N parameters together as a space separated string

Check the bash man page for the entry for '*' under Special Parameters.

join () {
echo "$*"
}

Bash parameter expansion delimiter

Agreeing with @choroba's comment about elegance, here are some other beholdables:

# seq is a gnu core utility
seq 1 10 | paste -sd:
# Or:
seq -s: 1 10

# {1..10} is bash-specific
printf "%d\n" {1..10} | paste -sd:

# posix compliant
yes | head -n10 | grep -n . | cut -d: -f1 | paste -sd:


Related Topics



Leave a reply



Submit