Como evitar o uso inútil de um gato ao analisar um arquivo?

7

Eu tenho um arquivo contendo uma lista de diretórios. Por exemplo

/foo/bar/dir1
/foo/bar/dir2
/foo/bar/dir3

Eu quero criar todos esses diretórios. Aqui está o que eu fiz:

for dir in $(cat myfile); do mkdir $dir; done

Qual seria a maneira correta de se fazer isso evitando o "uso inútil de gato"?

O ideal é que as respostas se concentrem no Ksh88, mas também estou interessado em outras shells

    
por rahmu 19.12.2011 / 17:00

6 respostas

13

A sugestão do AProgrammer de usar xargs geralmente é melhor, mas outra opção é usar o redirecionamento em um loop while , que permite que comandos adicionais sejam feitos e variáveis sejam definidas:

while read -r dir; do mkdir $dir; done < myfile

Um exemplo de uma estrutura mais complicada seria:

now='date +%Y%m%d.%H%M%S'
while read -r dir; do
    newdistfile="/tmp/dist-'echo $dir | tr / _'.tgz"
    mv $dir ~/backups/$dir.$now &&
        mkdir $dir &&
        tar xzfC $newdistfile $dir
done < myfile

Isso não é algo que xargs poderia fazer sem escrever um 'programa auxiliar'.

    
por 19.12.2011 / 17:29
11

Eu faria algo como

xargs mkdir < myfile
    
por 19.12.2011 / 17:04
10

Pelo menos no bash, desde que não existam nomes de arquivos contendo espaços e novas linhas, isto:

mkdir $(< myfile) 

funciona. Portanto, temos um uso inútil de for , xargs também.

< não inicia um novo processo no bash, em contraste com cat , mas eu não sei para ksh .

    
por 19.12.2011 / 20:15
3

Esta é a solução mais próxima do seu script original que ainda evita o gato inútil

for dir in $(<myfile); do mkdir $dir; done

Ele ainda contém um loop inútil.

    
por 19.12.2011 / 18:07
2

Eu não diria que é um uso inútil de gato.

No sentido clássico , um UUOC significa escrever:

cat file | some_command and its args ...

em vez do equivalente e mais barato

<file some_command and its args ...

ou (de forma equivalente e mais clássica)

some_command and its args ... < file

Neste caso:

for dir in $(cat myfile); do mkdir $dir; done

não há comando no qual a saída de cat esteja sendo canalizada.

Existem alternativas que não usam cat . Em particular, para o bash e o ksh $(<myfile) é provável que seja mais rápido que $(cat myfile) , embora nem todos os shells suportem essa construção. Mas eu não chamaria o código original de "uso inútil de gato" mais do que eu chamaria a solução de AProgrammer de "uso inútil de xargs".

    
por 19.12.2011 / 22:09
1

Com bash 4 e limitado por ARG_MAX

mapfile -t <file && mkdir -- "${MAPFILE[@]}"
    
por 21.10.2016 / 00:20

Tags