2
 file * |  grep 'ASCII text' | chmod -x 
chmod: missing operand
Try `chmod --help' for more information.

The above command gives me error.Basically I am trying to find all the files whose type is ASCII and change their permissions to -x.What mistake is there in above syntax?

Registered User
  • 1,463
  • 5
  • 18
  • 37

4 Answers4

3

One: grep 'ASCII text' returns not only the file name, but also the type of the file itself; you need to process the output to return only the file name

Two: chmod does not accept arguments from STDIN, which is what you're trying to do with the pipe |. You'll have to either use xargs or wrap the above in a for loop

That said, here are two solutions for you:

Solution #1: With Pipes

file * | awk '/ASCII text/ {gsub(/:/,"",$1); print $1}' | xargs chmod -x

Solution #2: With for-loop

for fn in $(file * | awk '/ASCII text/ {gsub(/:/,"",$1); print $1}'); do chmod -x "$fn"; done

Pick yer poison :-)

pepoluan
  • 5,038
  • 4
  • 47
  • 72
2

This should work regardless of whether filenames contain spaces or colons:

find -maxdepth 1 -type f -exec sh -c 'file -b "{}" | grep -sq ASCII' \; -print0 | xargs -0 chmod -x

You can remove the -maxdepth 1 to make it recursive.

There may be false positives if filenames themselves contain the string "ASCII".

Edit:

I incorporated pepoluan's suggestion of using the -b option for file so the filename isn't output for the test by grep. This should eliminate false positives.

Dennis Williamson
  • 62,149
  • 16
  • 116
  • 151
  • Then the grep should match with [[:space:]]ASCII ... for more details: http://stackoverflow.com/questions/448997/egrep-search-for-whitespace – pepoluan Mar 08 '11 at 11:27
  • @pepoluan: If you're talking about the part where I mention potential false positives, then it is correct that the more specific the regex is the less chance there is, but a filename could still match `[[:space:]]ASCII`. – Dennis Williamson Mar 08 '11 at 11:31
  • @Dennis: Ah, you're right. In that case, I suggest using `awk -F ":" '/ASCII/ && $1!~/ASCII/ {print $1}` – pepoluan Mar 08 '11 at 11:40
  • @pepoluan: But what if a file with "ASCII" in its name is an ASCII file? You don't want to falsely reject a file, either. Or if there's a file named "ASCII:ASCII" ... ad infinitum. You can reduce the chances, but you can't eliminate them. – Dennis Williamson Mar 08 '11 at 11:44
  • Heh, possible. Maybe better to have `for fn in *; do [[ $(file -b "$fn") =~ ASCII ]] && chmod -x "$fn"; done`. What do you think? – pepoluan Mar 08 '11 at 11:49
  • @pepoluan: That's a good idea. It can be incorporated into my version which doesn't use an explicit loop. – Dennis Williamson Mar 08 '11 at 11:53
  • @Dennis Williamson great answer.I observed you have given good answers to all my questions.Hope to get more support from you in near future also :) – Registered User Mar 08 '11 at 15:23
1
for f in `file * | grep "ASCII text" | awk "{print \\$1}" | awk -F ":" "{print \\$1}"`; do chmod -x "$f"; done
mkudlacek
  • 1,677
  • 1
  • 11
  • 15
1

And another one liner - be aware of the need to strip the : ASCII Text and quote the names too

file * | grep 'ASCII text' | sed  's|\(^.*\):.*|\"\1\"|'| xargs chmod -x
user9517
  • 115,471
  • 20
  • 215
  • 297