3

I'm getting a parsing error in the 773rd file of a folder. Is it possible to print the name of the file in bash?

I've tried using this to print it but it returns a blank.

files=(/path/to/files)
echo "${files[773]}"
AnonyMouse
  • 432
  • 8
  • 24

2 Answers2

7

Very close, but you need to actually do a glob to collect the list into your array, rather than having a list with only one element (the parent directory):

files=( /path/to/files/* )
echo "${files[772]}"

If you want to represent your filename in a way that represents nonprintable characters in a human-readable way, echo is the wrong tool. Instead, consider:

printf '%q\n' "${files[772]}"

If your path is coming from a variable, be sure to quote its expansion, but not the glob character:

files=( "$dir"/* )
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Should it not be 772 for the 773rd file? – Etan Reisner Sep 02 '14 at 19:38
  • 1
    @EtanReisner, indeed, it should... **if** the person asking was using 1-indexed math in the question itself. – Charles Duffy Sep 02 '14 at 19:38
  • 1
    (which... yes, letting people learn such things for themselves is rather mean, however effective; I've made the appropriate correction) – Charles Duffy Sep 02 '14 at 19:40
  • The double quotation mark in `echo "${files[772]}` is unnecessary – r3mainer Sep 02 '14 at 19:44
  • I was just going to put that in a comment on the OP but then your answer popped up so I added it there. – Etan Reisner Sep 02 '14 at 19:44
  • 1
    @squeamishossifrage, it's entirely necessary, albeit also to add a second closing one. Otherwise the filename prints wrong if it contains a run of multiple spaces, or a glob sequence that can expand, or any characters inside of IFS. (By the way -- did you know that filenames with newlines are valid in UNIX? But if you don't quote your variable expansions, `echo` will never tell you they exist...) – Charles Duffy Sep 02 '14 at 19:45
  • @CharlesDuffy:- +1 No but I was juggled up when trying to write but deleting my answer as it was a duplicate. :) – Rahul Tripathi Sep 02 '14 at 19:49
  • @CharlesDuffy That's interesting! +1 – r3mainer Sep 02 '14 at 19:50
  • 1
    @squeamishossifrage, argh, I actually gave bad repro steps earlier. `touch 'foo * bar' baz qux; files=( foo* ); echo ${files[@]}` vs the same with `echo "${files[@]}"` will better demonstrate the difference (on bash, not zsh; zsh breaks POSIX to provide behavior more in line with user expectations). – Charles Duffy Sep 02 '14 at 21:04
  • How to add the recursive feature to it? @CharlesDuffy – Dr.jacky Jan 16 '22 at 15:17
  • 1
    @Dr.jacky, which shell? In bash, `shopt -s globstar` to make `**` be used to recurse. (BTW, arguably this should be its own question -- and in some interpretations it _already is_ its own question; see f/e answers teaching the technique on [recursively look for files with a specific extension](https://stackoverflow.com/questions/5927369/recursively-look-for-files-with-a-specific-extension)) – Charles Duffy Jan 16 '22 at 16:45
0

You actually need to execute the bash ls command to do that:

ls | sed -n 773p

you can, of course, write it to a variable:

MY_FILE=$(ls | sed -n 773p)

And, as well, instead of 773 you could use the variable as well. Hope it helps.

Hrvoje
  • 189
  • 1
  • 7