basename
não pega uma lista de caminhos (sem falar de um delimitado por novas linhas), leva um único caminho (opcionalmente seguido por um sufixo para remover).
Além disso, quando você usa o comando (como echo
) em backticks, o shell pega a saída desse comando, divide em "palavras" separadas por espaço em branco (geralmente espaços, tabulações e novas linhas, mas você pode alterá-lo com $IFS
), expande todos os curingas encontrados e passa o resultado de tudo isso para o outro comando ( basename
neste caso). Como resultado, as novas linhas na saída echo
são tratadas como apenas mais espaços em branco entre as palavras, não passadas para basename
. Então, este comando:
basename 'echo -e '/foo/bar \n /food/baz \n /oof/rab''
é equivalente a:
basename "/foo/bar" "/food/baz" "/oof/rab"
... e aparentemente quando basename
obtém três argumentos como este, imprime o nome base de cada argumento separadamente. A página man do basename
não documenta esse comportamento, então, se houver alguma coisa, é um erro não dar um erro nesse caso.
Da mesma forma, este comando:
basename 'echo -e '/foo/bar \n /food/baz''
é equivalente a
basename "/foo/bar" "/food/baz"
... mas, neste caso, o comportamento de basename
é definido e é bem diferente - ele usa o nome base do primeiro argumento, remove o segundo argumento de seu final (se corresponder) e imprime o resultado. "bar" não termina com "/ food / baz", então apenas imprime "bar".
Além disso, echo -e
é estranhamente não-portável (mesmo entre versões diferentes do OS X!). Abaixo, usei o formato de string $' '
do bash para obter as sequências de escape traduzidas.
Se você quiser imprimir os nomes base de uma lista separada por novas linhas de caminhos, use um loop para executar basename
em cada um separadamente:
while read -r filepath; do
basename "$filepath"
done <<< $'/foo/bar \n /food/baz'
Ou use apenas sed
para excluir até o primeiro "/" em cada linha:
echo $'/foo/bar \n /food/baz \n /oof/rab' | sed 's@^.*/@@'