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 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"
How to split a string in shell and get the last field
You can use string operators:
$ foo=1:2:3:4:5
$ echo ${foo##*:}
5
This trims everything from the front until a ':', greedily.
${foo <-- from variable foo
## <-- greedy front trim
* <-- matches anything
: <-- until the last ':'
}
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"
How to split the string with delimiter and swap the substring's position in bash?
Assumptions/understanding:
- the objective is to rename the files (the question mentions
Goal is to name them as ...
but there is no mention of themv
command ... ???) - all file names contain a single period
- we want to switch the before-period/after-period portions of the file names to create new file names
- no files exist with the new file name (eg, we don't currently have files named
a.txt
andtxt.a
)
One idea using parameter expansion which allows us to eliminate the overhead of sub-process calls:
for fname in *.txt
do
new_fname="${fname#*.}.${fname%.*}"
echo mv "${fname}" "${new_fname}"
done
For files names a.txt
, b.txt
and c.txt
this generates:
mv a.txt txt.a
mv b.txt txt.b
mv c.txt txt.c
Once OP is satisfied with the results the echo
can be removed and the script should perform the actual mv
/rename.
split based on the last dot and create a new column with the last part of the string
You may use this sed
:
sed -E 's/^([[:blank:]]*[^[:blank:]]+)\.([^[:blank:]]+)/\1 \2/' file
5_8S_A.3-C_1 A 50
6_FS_B.L.3-O_1 A 20
H.YU-201 D 80
UI-LP.56.2011 A 10
Details:
^
: Start([[:blank:]]*[^[:blank:]]+)
: Capture group #2 to match 0 or more whitespaces followed by 1+ non-whitespace characters.\.
: Match a dot. Since this regex pattern is greedy it will match until last dot([^[:blank:]]+)
: Capture group #2 to match 1+ non-whitespace characters\1 \2
: Replacement to place a space between capture value #1 and capture value #2
Extract substring before dot
You need to use %%
to remove the longest match from the end:
$ echo "${s%%.*}"
4
From the docs:
${parameter%%word}
Remove Largest Suffix Pattern. The word shall be expanded to produce a pattern. The parameter expansion shall then result in parameter, with the largest portion of the suffix matched by the pattern deleted.
Related Topics
How to Authenticate Username/Password Using Pam W/O Root Privileges
Would It Be Possible to Read Out Physical Keyboard Strokes in Node.Js
Raising Hard Limit on Rlimit_Nofile System-Wide on Linux
How Does The 64 Bit Linux Kernel Kick Off a 32 Bit Process from an Elf
$${Home} or ${Home} in Makefile
Setup Sftp to Use Public-Key Authentication
How to Recursively Unzip Nested Zip Files
Installing 32 Bit Libraries (Glibc) on 64 Bit Rhel Without Using Yum
Syntax Error Near Unexpected Token 'Do' When Run with Sudo
Running R in Batch Mode on Linux: Output Issues
Write and Read from Ttyusb0, Can't Get Response
Installing Ffmpeg on Amazon Linux - Cpp, Gcc & Libstdc++ Dependancies
How to Avoid Having Version Numbers in .So File Name
What Is The Maximum Number of Subdirectories Allowed in Ext4
What Is The Current State of Tail-Call-Optimization for F# on Mono (2.11)