I am able to do this in shell command line.

filename="/home/vikrant_singh_rana/testing/110001_ABC Traffic_04May2020_header_only.csv"
output_filename=$(basename "$filename")

cat "/home/vikrant_singh_rana/testing/110001_ABC Traffic_04May2020_header_only.csv" > /home/vikrant_singh_rana/enrichment_files/"$output_filename"

It was able to read given file from '/home/vikrant_singh_rana/testing' and has written file with same name to other dir '/home/vikrant_singh_rana/enrichment_files'

When I am doing same thing in shell script. Its not working


# Go to where the files are located
#reading file from directory
for filename in $filedir; do
        #echo $filename
        output_filename=$(basename "$filename")
        #echo $output_filename

done > /home/vikrant_singh_rana/enrichment_files/"$output_filename"

while running this I am getting this error

/home/vikrant_singh_rana/enrichment_files/: Is a directory
  • You're using "$output_filename" outside the loop, but it's first set inside the loop. (Think of what you're running as { for fileiname in ... do ...; done; } > /home/vikrant_singh_rana/enrichment_files/"$output_filename" What would the point even be, since the variable changes inside the loop each time, but you're only redirecting once?
    – muru
    Jun 9 '20 at 3:23
  • Why do you use cat for copying files...? Jun 9 '20 at 3:25
  • that I just did for checking the command.. may be I need to use a cp or move statement inside a loop itself Jun 9 '20 at 3:27
  • 1
    @alecxs That is not correct. cp uses the existing inode. Even cp -p does; it just changes the metadata. sed -i is something completely different because it creates a temporary file and renames that in the end, i.e. replaces the old inode with the new one. Jun 11 '20 at 9:54
  • 1
    @HaukeLaging thx for clarifying, seems i have mixed up things regarding inodes. i just remember i have had problems with cp doesn't work for secontext (even busybox cp with -c flag did not work on debian) so i ended up with cat
    – alecxs
    Jun 11 '20 at 10:02

You use pathname expansion (*) incorrectly. And as muru's comment states you mix the use of variables inside and outside the loop.

#! /bin/bash

cd "$source_dir_path" || exit 1
for filename in *; do
    test -f "$target_path" && { echo "File '${filename}' exists; skipping"; continue; }
    cp -p "$filename" "$target_path"
  • actually I was reading file from dir and was doing something on it and trying to write that new file with same name to other directory Jun 9 '20 at 4:10
  • @vikrantrana Then you just have to exchange the cp line against the required command. Jun 9 '20 at 4:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.