I'm trying to store the contents of my one variable in my for loop in my other variable, but I get

0403-006 Execute permission denied


while IFS='|' read -r col1 col2 col3 col4 col5 col6 col7
for f in directory/*
        files=$($f | awk -F "_" '{print $3}')
        echo $files
done <test.txt

I have full permissions to run this, it errors when I put in the echo $files

  • Are you parsing the file name which is looped with $f? if it so, try files=$( echo "$f" | awk -F "_" '{print $3}')
    – Siva
    Jun 15, 2018 at 17:04
  • This is probably related to your other recent questions, right? What is it you want to do here? Don't you want to use the variables that you've just read from test.txt? Is the end result a filename (or pattern?) that you construct from col1 etc.? What should that name/pattern look like?
    – Kusalananda
    Jun 15, 2018 at 17:31

3 Answers 3


It's very unclear what your script is doing and looks miswritten altogether. You need to provide more details to find out what exactly is wrong and what you want to achieve. My guess is that the error comes from this line:

files=$($f | awk -F "_" '{print $3}')

In particular, you need to realise what happens here:

$f | awk -F "_" '{print $3}'

You're executing $f, which is one of the files directory/*. One of them is 0403-006, and you can't execute it.

What about the variables col1, col2, etc? The data read from test.txt is completely unused.

Present a minimal and complete example with input data and expected output, as this script doesn't look sane even if my guess is right.


Looking at your own answer, it is clearer what it is that you actually would want to do.

Here is my own take on that:




dups=$( mktemp )
cut -d '|' -f 4 <"$dupsfile" >"$dups"

for pathname in "$indir"/*; do
    [ ! -f "$pathname" ] && continue

    string=$( printf '%s\n' "${pathname##*/}" | cut -d '_' -f 4 )

    if grep -qxF "$string" "$dups" then
        echo mv "$pathname" "$baddir"

rm "$dups"

The difference between your own answer and this is that the file list is only generated once and not once per line in the data file.

The data file is parsed in such a way that its 4th |-delimited column is extracted and saved into a temporary file. This file is consulted once for each file in the directory that you are investigating, using grep. If the 4th _-delimited bit of the filename is present in that temporary file, the file is moved. Remove the echo to actually move files.


I've modified my script to do exactly what I want

while IFS='|' read -r col1 col2 col3 col4 col5 col6 col7
    for f in /archival/test/sppark/datapdf/staging/renamedTriage/*
        files=$(echo "$f" | awk -F "_" '{print $4}')
        if [[ $col4 == $files ]]; then
            mv $f /archival/test/sppark/datapdf/staging/badFiles/
done </archival/test/sppark/dataindex/staging/duplicates.txt

My while loop reads my txt file, reads each column delimited by |. I have a for loop to loop through each file in my directory, and if my $col4 is the same as the $files, it will then move the file to my specified directory

Not the answer you're looking for? Browse other questions tagged .