Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to learn UNIX commands and I'm playing this game to learn and I'm really stuck at the moment. I'm in a server through ssh and the directory is full of random files and folders and the password for the next level is inside one of the files. I have been told that the file has the following attrbutes:

  • human-readable
  • 1033 bytes
  • non-executable

I am guessing that I should use the find command and I tried find ! -executable but that returned a load of files. The only human-readable help I can find in the manual or online is printing out the file sizes in human readable. So I'm a bit lost there?

Also I did try find ~ -size 1033b but that returned nothing. But when I tried find ~ -size -1033b it returned every file in the directory.

share|improve this question

migrated from stackoverflow.com Jul 16 '12 at 2:05

This question came from our site for professional and enthusiast programmers.

add comment

2 Answers 2

find . -type f -readable -size 1033c ! -executable

Note that I used c instead of b for the file size. b is for 512 byte blocks. c is for actual bytes.

share|improve this answer
2  
I don't think -readable means human-readable (i.e. not binary) –  hhaamu Jul 16 '12 at 9:04
1  
@hhaamu - right. However, it's probably not bad to filter out files the user has no rights to read! In order to determine if a file contains human-readable content, pipe the names returned by find to file. –  D_Bye Jul 16 '12 at 11:20
add comment

To filter out the human-readable file names, you can make use of the [:print:] (printable) character class name. You will find more about such classes in the manual for grep.

find . -type f -size 1033c -name "[[:print:]]*" ! -executable

On a second thought, the "human-readable" requirement might refer to the file's content, instead of its name. In other words, you would be searching for text files. That is a little more tricky. As @D_Bye suggested in a comment, you should then use the file command to determine the file content type. But it would not be a good idea to run file after a pipe, because it would complicate the task of displaying the file's name. Here's what I suggest:

find . -type f -size 1033c ! -executable -exec sh -c 'file -b $0 | grep -q text' {} \; -print

This is briefly how the file-part works:

  • The -exec predicate executes sh -c 'file -b $0 | grep -q text' FILENAME for each FILENAME that satisfies all the previous conditions (type, size, non-executable).
  • For each of those files, a shell (sh) runs this short script: file -b $0 | grep -q text, replacing $0 with the filename.
  • The file program determines the content type of each file and outputs this information. The -b option prevents printing the name of each tested file.
  • grep filters the output coming from file program, searching for lines containing "text". (See for yourself, how a typical output of the file command looks like.)
  • But grep does not output the filtered text, because it has the -q (quiet) option given. What it does, is just change its exit status to either 0 (which represents "true" - the filtered text was found) or 1 (meaning "error" - the text "text" did not appear in the output from file).
  • The true/false exit status coming from grep is passed further by sh to find and acts as the final result of the whole "-exec sh -c 'file $0 | grep -q text' {} \;" test.
  • In case the above test returned true, the -print command is executed (i.e. the name of the tested file is printed).
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.