I have some files in directory , Need to split them by _ number
Example : I have files like ODRD_AzureData_Linux_x64_19.1.0.0.7.tar,
I want to split that by
name : ODRD_AzureData_Linux_x64
version :19.1.0.0.7
I was tried with this not getting results : name='$filename | cut -f1 -d'.'' , I am not getting expected results ,
please help me
CodePudding user response:
You can use bash
glob parameter expansion as explained here and here to extract the file name and version number and store them in bash array (assuming there are multiple files with .tar
extension).
I have written a simple bash script for you (let's name it listfiles.sh
), you can refer and modify it as per your needs:
#!/bin/bash
declare -a arrFiles
declare -a fname
declare -a fversion
for file in "$1"/*
do
arrFiles=("${arrFiles[@]}" "$file")
done
idx=0
for f in "${arrFiles[@]}"
do
extension="${f##*.*.}"
fname=("${fname[@]}" "$(basename -s ".$extension" "${f}")")
fversion=("${fversion[@]}" "${fname[idx]#*_[0-9]}")
# echo ${fversion[idx]}
idx=$((idx 1))
done
echo "FileName: " "${fname[@]%_*}"
echo "Version: " "${fversion[@]}"
To use it, you need to call this script on the folder where your files are stored, e.g.
bash listfiles.sh Documents
CodePudding user response:
To be compatible with POSIX shell, and avoid spawning more than one process (subshell), you can use the built-in parameter-expansions supported by POSIX shell to trim from the left and right ends of the filename as needed breaking the filenames into the name
and ver
you desire. The basic approach is to loop over the filenames in a directory and apply the parameter expansions as follows:
#!/bin/sh
for f in *; do # loop over each file in current directory
[ ! -f "$f" ] && continue # skip anything not a file
name="${f%_*}" # trim from right to first '_'
ver="${f##*_}" # trim from left to last '_'
ver="${ver%.*}" # trim from right to first '.'
printf "name: %s\nver: %s\n" "$name" "$ver" # output results
done
The parameter expansions supported by POSIX are:
${var#pattern} # Strip shortest match of pattern from front of $var
${var##pattern} # Strip longest match of pattern from front of $var
${var%pattern} # Strip shortest match of pattern from back of $var
${var%%pattern} # Strip longest match of pattern from back of $var
(note: pattern
can contain the normal globbing characters such as '*'
)
Example Output
With your example above, you would receive the following output:
name: ODRD_AzureData_Linux_x64
ver: 19.1.0.0.7
CodePudding user response:
It’s a little difficult to give a catch-all solution since we aren’t sure of the format or the the shell. But let’s assume this:
- Shell is BASH (Or any POSIX compliant shell)
- The format is always name_version.*
You can use parameter-expansion to solve this nicely. Using your example:
#!/bin/bash
<SNIPPED>
# This doesn’t have to be hard-coded, it’s just for simplicity
input=ODRD_AzureData_Linux_x64_19.1.0.0.7.tar
# Remove the lastmost ‘_’ and everything after.
name=“${input%_*}”
# Remove the lastmost ‘_’ and everything before.
version=“${input%*_}
# Remove the firstmost ‘.’ with a letter following
# and everything after.
version=“${version#.[a-zA-Z]*}
# ^ We need to do this to remove the extension.
# This may break if version includes “alpha/beta”
<SNIPPED>
This particular process is known as “pattern-removal”. However, Bash parameter-expansion has a lot of neat tricks up its sleeve I recommend you check out.
After reading David’s comment I’ve, learned that a subset of parameter-expansions are POSIX compliant and, adjusted my answer accordingly. Shells are beautiful things.