Atribuindo apenas parte de uma string a uma variável no bash

11

Recebo do usuário um determinado caminho de arquivo absoluto e quero criar uma variável que seja uma sequência que não inclua apenas os PRIMEIROS dois componentes do caminho do arquivo, mas sem imprimi-lo ou algo assim.

Por exemplo, o caminho absoluto pode ser:

/home/myusername/folder1/folder2/folder3

E é salvo em "target_path", e eu quero que "mydir" seja apenas:

/folder1/folder2/folder3

Tentei usar o comando cut de maneiras diferentes, mas sem sucesso.

Vida de pi
fonte
O diretório /home/usernamereal $HOMEdo usuário que está chamando? se assim você poderia removê-lo simplesmente usando mydir="${target_path#$HOME}"eu acho #
steeldriver

Respostas:

15

Usando a manipulação de string do bash :

$ a=/home/myusername/folder1/folder2/folder3
$ echo "${a#/*/*/}"
folder1/folder2/folder3

Portanto, a string que você deseja seria (adicionando de volta a barra inicial):

b="/${a#/*/*/}"

Para uma variável a, ${a#foo}removerá a string mais curta correspondente foodesde o início de a. Portanto, removemos a string mais curta que contém três /(incluindo a barra inicial no caminho), para remover os dois primeiros componentes do caminho absoluto.

muru
fonte
O caminho pode ter 30 pastas e quero incluir apenas as últimas 28. Isso ainda funcionará?
A vida de pi
@Lifeofpi por que não?
Muru
9

Aqui está um exemplo usando cut

echo "/home/myusername/folder1/folder2/folder3" | cut -d '/' -f4- 

folder1/folder2/folder3

Se você precisar da liderança, /poderá anexar | sed 's/^/\//'ao final da sua linha.

Você precisa -f4-porque -d '/'diz cutpara usar /como delimitador entre os campos. Portanto, o primeiro campo vem antes do primeiro delimitador; nesse caso, o primeiro campo está vazio. O mesmo folder1acontece com o quarto campo e -f4-diz ao cut para usar todos os campos a partir do quarto.

Guntbert
fonte
7

Você pode usar a expansão de parâmetros do bash da seguinte maneira:

target_path=/home/username/folder1/folder2/folder3
myvar="/${target_path#/*/*/}"

Depois disto:

echo $myvar

dá:

/folder1/folder2/folder3

Ele funciona removendo a primeira correspondência do padrão /*/*/da variável target_path, usando a ${target_path#pattern}sintaxe de expansão do parâmetro shell. Infelizmente, isso remove o primeiro /caractere, e é por isso que esse caractere deve ser incluído explicitamente ao definir a variável myvar.

Aviso: você deve verificar se a variável target_path contém alguns caracteres e tem mais de dois segmentos de caminho antes de usar este método. Por exemplo target_path=/home/username/, se , então myvar=/. Isso pode ser perigoso para o seu sistema se você estiver executando algo parecido rm -rf "$myvar"*. Não tente isso!

Arronical
fonte
O caminho pode ter 30 pastas e quero incluir apenas as últimas 28. Isso ainda funcionará?
Life of pi
Definitivamente, isso apenas cortará os dois primeiros, independentemente do tamanho do caminho.
Arronical 10/11/16