Home > Software engineering >  Need to split file name form _ some number in shell script
Need to split file name form _ some number in shell script

Time:01-17

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.

  • Related