jp72924
jp72924

Reputation: 3

how to replace all substrings of a array of strings in bash?

I'm trying to list all files in a sub-directory without their path, I just want the file name and extension, but Bash substitution doesn't work with all paths in an array, it only works with the first element.

Code:

#!/usr/bin/bash

NAME="$(pwd | grep -o '[^/]*$')"

# ls src -R
PATH="$(ls src/*.{cpp,hpp} 2> /dev/null)"
if [ 0 -eq "${#PATH[@]}" ]; then
    echo "The project has no source code file yet."
    exit 0
fi

EMPTY=''
for FILE in "${PATH[@]}"; do
    echo "${FILE/src\//$EMPTY}"
done

Directory tree:

FileReader
├── bin
├── make.sh
├── obj
└── src
    ├── FileReader.cpp
    ├── FileReader.hpp
    └── main.cpp

Expected:

$ bash make.sh

FileReader.cpp
FileReader.hpp
main.cpp

Output:

$ bash make.sh

FileReader.cpp
src/FileReader.hpp
src/main.cpp

Upvotes: 0

Views: 563

Answers (1)

Shawn
Shawn

Reputation: 52579

Since parsing ls is bad, I'd do something like:

#!/usr/bin/env bash

# If no matching files, globs expand to an empty string instead of the pattern
shopt -s nullglob
declare -i count=0
for file in src/*.[ch]pp; do
    count+=1
    printf "%s\n" "$(basename "$file")"
done

[[ $count -eq 0 ]] && echo "The project has no source code file yet."

to avoid issue with funny characters in filenames. basename(1) removes leading directory components from a filename (And optionally a given extension).

You can also safely get the files in an array with files=( src/*.[ch]pp ) and use something closer to your original approach. I would definitely avoid calling a variable PATH though as that conflicts with a built in one, though.

Array based version (This one uses the ${variable#pattern} parameter expansion syntax that strips the matched text of a pattern from the beginning of the variable's value):

#!/usr/bin/env bash

shopt -s nullglob
files=( src/*.[ch]pp )

if [[ "${#files[@]}" -eq 0 ]]; then
    echo "The project has no source code file yet."
else
    printf "%s\n" "${files[@]#*/}"
fi

Upvotes: 1

Related Questions