sed command to change names for few files in different directories at once

Viewed 59

I have few folders as S1S, S2S ,S3S ... , In each of these folders there is a file1 . This file1 in each folder consistent of

1990.A.BHT_S1S.dat
1994.I.BHT_S1S.dat
1995.K.BHT_S1S.dat
likewise S1S extension change according to the folder.

I'm trying to change these names into 1990.A.BHT type for all folders using this command

for dir in S*
do
cd $dir
sed -i 's/_${dir}\.dat//g' file1 > file2
cd ../
done

but i get an empty file for file2

Can someone help me to figure out my mistake please?

2 Answers

This might work for you (GNU sed and parallel):

parallel sed 's/_{}\.dat//' {}/file1 \> {}/file2 ::: S*S

Create a new file file2 in each directory S1S S2S S3S ... from file1 with the string _SnS.dat removed (where SnS represents the current directory).

There are several problems here. First, as konsolebox said in a comment, sed -i modifies the original file rather than producing output that can be redirected with >, so you need to remove that option.

Second, variables don't expand in single-quoted strings, so 's/_${dir}\.dat//g' doesn't use the dir variable, it just treats that whole thing as a literal string.

The third is probably ok, but using cd in a script is dangerous, because if it fails for some reason the rest of the script will run in unexpected places, with possibly very bad results. It's generally better to use explicit paths, like sed ... "$dir/file1" instead of cding to $dir and then using sed ... file1.

Finally (again probably ok here) is that you should almost always put double-quotes around variable references, to avoid weird parsing of some characters.

So here's how I'd rewrite the script snippet:

for dir in S*
do
    sed "s/_${dir}\.dat//g" "$dir/file1" > "$dir/file2"
done

p.s. shellcheck.net is good at spotting common mistakes in shell scripts; it spots three of the four problems I saw (all but the sed -i problem). I recommend running your scripts through it as a check.

Related