Eu tenho um arquivo .txt que contém um texto como este
A1/B1/C1
A2/B2/C2
A3/B3/C3
Eu quero um script que leia o arquivo .txt para cada linha e crie um diretório com base na primeira palavra (A1, A2, A3)
Eu criei um script como este:
file="test.txt"
while IFS='' read -r line
do
name="line"
mkdir -p $line
done <"$file"
Enquanto o executo, ele cria o diretório A1 e também os subdiretórios B1 e C1. o mesmo acontece com outra linha (A2 * e A3 *)
O que devo fazer para criar apenas diretórios A1, A2, A3?
Não quero criar o nome como A1 / B1 / C1 com o caractere '/'. Eu só quero pegar a palavra antes do caractere '/' e torná-la nome do diretório. Apenas "A1" "A2" "A3".
fonte
xargs -a<(....)
que ao invés de<dirlist.txt cut -d/ -f1 | xargs
?tr
abordagem - acabei de perceber queparallel
ela é coberta por padrão.xargs -a<(....)
que ao invés de um cachimbo - porque eu gosto dessa maneira, simples assim. :)<(...)
também ajuda com os espaços, por isso é definitivamente a melhor escolha - acho que ninguém estava usando esse descritor de arquivos.cut <dirlist.txt
invés de apenascut dirlist.txt
?Você precisa definir seu
IFS='/'
pararead
e, em seguida, atribuir cada primeiro campo à variável separadafirst
e o restante dos campos à variávelrest
e apenas trabalhar no valor do primeiro campo (ou você poderead -ar array
criar uma única matriz e usar"${array[0]}"
o valor do primeiro campo).Ou em fila única para quem gosta:
Ou crie todos os diretórios de uma só vez:
A cotação ANSI-C
$'...'
é usada para lidar com nomes de diretório que contêm caracteres especiais.Note que o
_
(pode ser qualquer caractere ou string) no final será argv [0] para obash -c '...'
e o$@
will contém o restante dos parâmetros a partir de 1; sem isso no segundo comando, o primeiro parâmetro para omkdir
será perdido.Ao
${1%%/*}
usar a expansão de substituição de parâmetro shell (POSIX sh / bash / Korn / zsh) , remove a maior correspondência possível de uma barra seguida por qualquer coisa até o final do parâmetro que passa para ela, que é uma linha que é lida por xargs ;Ps:
echo
na frente domkdir
para criar esses diretórios.-d'\n'
por-0
se sua lista estiver separada por caracteres NUL em vez de uma linha\n
eletrônica (suponha que exista / esteja nova linha incorporada no nome do diretório).fonte
Conteúdo de
test.txt
:Script para criar
A[123]
pastas:Saída de
ls
:fonte
A 12"x4" dir/B b/C c
:?Para um caso simples, como mostrado no exemplo de entrada da pergunta, basta usar
cut
e passar a saída paramkdir
viaxargs
Para lidar com casos em que o nome do diretório pode conter espaços, podemos adicionar
-d '\n'
à lista de opções:Para variações mais complexas,
A 12"x4" dir/B b/C c
como sugerido por @OleTange nos comentários, é possívelawk
criar uma lista separada por nulos em vez de lista separada por nova linha.@dessert nos comentários se perguntou se
printf
pode ser usado em vez decut
, e tecnicamente falando, pode ser usado, por exemplo, limitando a sequência impressa à largura de apenas três caracteres:Não é a maneira mais limpa, mas prova que
printf
pode ser usada. Obviamente, isso fica problemático se o nome do diretório tiver mais de 3 caracteres.fonte
A 12"x4" dir/B b/C c
:?usando Perl:
Ou
se queremos aceitar espaços em nomes de diretórios
fonte
perl -ne 'mkdir for /^([^\/]+)/' list.txt
para cobrir espaços em nomes de dir. Finalmente preciso aprender Perl - obrigado!O GNU Parallel pode ser um exagero para a tarefa, mas se você quiser fazer outras coisas para cada linha, poderá ser útil:
Ele lida corretamente com entradas como:
fonte