Dave
Dave

Reputation: 17

How do you alter the contents of an array with sed in BASH shell script?

I created an array of names of all files in the current directory ending with .cpp and want to create the same array with the .cpp replaced with .o

cppfield=$(ls *.cpp)
ofield=$(ls *.cpp | awk '{print}' ORS=' ' | sed s/.cpp/.o/g)

but it is not working only the first argument has the .cpp switched with .o

Upvotes: 0

Views: 100

Answers (3)

Alfe
Alfe

Reputation: 59436

Don't use ls to get directory contents for further processing. It will be hard to handle the file names which have spaces and newlines in them correctly.

Better you use find like this:

x() { sed 's/\.cpp$/.o/' <<< "$1"; }
export -f x
find . -maxdepth 1 -exec bash -c 'x "{}"' \;

Now the answer is not about arrays anymore, but that's because I want to point out that storing the output of ls in an array is already the beginning of the problem. Maybe avoid arrays for this task altogether.

Upvotes: 0

Etan Reisner
Etan Reisner

Reputation: 80931

Is this what you are trying to do.

$ ls
a1.cpp  a2.cpp  a3.cpp  a4.cpp  a5.cpp  a6.cpp
$ cppfield=(*.cpp)
$ declare -p cppfield
declare -a cppfield='([0]="a1.cpp" [1]="a2.cpp" [2]="a3.cpp" [3]="a4.cpp" [4]="a5.cpp" [5]="a6.cpp")'
$ ofield=("${cppfield[@]/%.cpp/.o}")
$ declare -p ofield
declare -a ofield='([0]="a1.o" [1]="a2.o" [2]="a3.o" [3]="a4.o" [4]="a5.o" [5]="a6.o")'

Use globbing to fill in the array to handle filenames safely. Don't parse ls

Use Shell Parameter Expansion to replace .cpp with .o on every array element.

Expand an array in quotes and store the result in a new array.

Upvotes: 2

bgoldst
bgoldst

Reputation: 35314

You can use pattern substitution when you expand the array:

bash> a=(a.cpp b.cpp);
bash> a=("${a[@]/%.cpp/.o}");
bash> echo "${a[@]}";
a.o b.o

Upvotes: 2

Related Questions