Uma lista segura de arquivos é produzida com um *
sem aspas, sem ser usado:
$ echo *
Vamos ter alguns arquivos para testar:
$ mkdir test-dir; cd test-dir
$ touch clean normal_file 'a%b' 'has two spaces' '*' 'a*b' '?' 'a?b'
$ touch '$' 'a$b' '%' 'a%b' $'new\nline' $'em\u2001quad' 'normal_file'
O comando echo *
produzirá, com os arquivos acima:
? $ * % a?b a$b a*b a%b clean em quad has two spaces new
line normal_file
Uma lista separada por espaço, que, sim, tem duas linhas, pois há um arquivo com uma nova linha em seu nome.
Uma maneira mais fácil de ver os arquivos é citar o nome deles com printf '%q'
e adicionar uma nova linha, como printf '%q\n'
, recebemos uma lista limpa de arquivos:
$ printf '%q\n' *
\?
\$
\*
%
a\?b
a\$b
a\*b
a%b
clean
$'em201quad'
has\ two\ spaces
$'new\nline'
normal_file
Claro, você precisa selecionar alguns arquivos, não todos, como com o plain *.
Então, criamos um padrão de todos os caracteres para corresponder: ?$*%
.
No entanto, a maioria desses caracteres é "especial" e precisa ser citada quando aparece em alguns pedidos. Especificamente, se *
ou ?
seguir $
, eles serão expandidos pelo shell, o que poderia criar problemas.
É imperativo citar o $
.
Então, uma maneira fácil de obter todos os outros caracteres citados é usar printf '%q' ?\$*%
. Isso produzirá: \?\$\*%
. Se a barra invertida não for estritamente necessária, ela não produzirá nenhum efeito negativo, o caractere de escape ainda funcionará.
Para essa lista, precisamos adicionar alguns caracteres em branco. Mas a inclusão da nova linha se torna um problema sério. A maneira mais fácil de lidar com a nova linha dentro de uma classe de caracteres é usar [[:space:]]
, que incluirá nova linha, espaço, tabulação e alguns outros caracteres de espaço como em-traço.
Portanto, o comando se torna:
$ printf '%q\n' *[\?\$\*%[:space:]]*
\?
\$
\*
%
a\?b
a\$b
a\*b
a%b
$'em201quad'
has\ two\ spaces
$'new\nline'
Observe que os nomes dos arquivos clean
e normal_file
não foram listados, conforme necessário.