2

I'm trying to list all the files with names no longer than 250 characters (including the directory it is part of, from the relative path my command is inside).

I've seen a similar thread , but that will only list the files recursively.

Any idea on how to modify script to only show files with names no longer than 250 characters (including the relative path)?

2
  • possible duplicate of Find files by the length of filename Commented Apr 29, 2015 at 13:21
  • When I use this: find . -regextype posix-extended ! -regex '.{251,}' ! -type d It shows: find: unrecognized: -regextype I also tried : find . ! -path "$(printf %251s | tr ' ' '?')*" Unfortunately, for some reason, when i calculate the output, they are only 220 characters... Commented Apr 29, 2015 at 16:14

2 Answers 2

4

With GNU find:

find . -regextype posix-extended ! -regex '.{253,}' ! -type d

(that prints a ./ prefix which is not included in the 250 count).

With zsh:

setopt extendedglob # if not already in your ~/.zshrc
printf '%s\n' **/*~?(#c251,)(D^/)

That's all paths recursively (**/*) including hidden ones ((D)), but not (^) those of type directory (/), except (~) those that match ?(#c251,), that is that contain 251 characters or more.

POSIXly:

find . ! -path "$(printf %253s | tr ' ' '?')*" ! -type d

(note that there's nothing on Unix that guarantees that file names are made of valid characters. Except for the zsh one, those solutions may also report files whose path contain sequences of bytes that don't form valid characters (adding -path '*' may help excluding those). If you want to match on the number of bytes as opposed to number of characters in your locale, you can fix the locale to C with export LC_ALL=C).

3
  • POSIX part is tricky, +1! Commented Apr 29, 2015 at 14:08
  • When I use this: find . -regextype posix-extended ! -regex '.{251,}' ! -type d It shows: find: unrecognized: -regextype I also tried : find . ! -path "$(printf %251s | tr ' ' '?')*" Unfortunately, for some reason, when i calculate the output, they are only 220 characters.... Commented Apr 29, 2015 at 15:34
  • 1
    @tuckker. The first one requires GNU find. Yours is probably busybox find. 220 is not longer than 250, so by your requirements, those files should be listed. Update your question if that's not what you want. Commented Apr 29, 2015 at 16:37
3

POSIXly:

$ find . -type f -exec sh -c '
    for f do
      [ "${#f}" -le 252 ] &&
      printf "%s\n" "$f"
    done
' sh {} +

POSIX defined ${#parameter} as the length in characters of value parameter, but the behaviour may varies in some shells. bash, zsh, yash count characters, dash count bytes. ksh93 has a random bug depends on its implementation.

4
  • Note that for paths that contain multi-byte characters or sequences of bytes that don't form valid characters, the behaviour varies across sh implementations (${#f} counts bytes in ksh and dash and characters in bash, zsh and yash; yash chokes on invalid characters). Commented Apr 29, 2015 at 14:27
  • @StéphaneChazelas: Is it a weird behaviour since when POSIX specified that ${#parameter} is the length in characters of the value of parameter? Commented Apr 29, 2015 at 14:53
  • Yes, it's a bug in those shells. That was discussed on the austin group ml not so long ago. I was partly wrong for ksh above. ksh93 -c 'echo "${#1}"' sh $'\ue9\xe9' gives me 19, but that's a random bug in ksh93. With mksh, it gives me 3 but 2 with mksh -o utf8-mode. Commented Apr 29, 2015 at 15:12
  • @StéphaneChazelas: I have ksh version sh (AT&T Research) 93u+ 2012-08-01 both in Debian and OSX. The one in OSX return 2, but Debian return 53 for your example. Commented Apr 29, 2015 at 15:20

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.