Como eu escrevo um script que itera sobre valores de entrada? [fechadas]

1

Eu estou tentando escrever um script que itera sobre um número não especificado de valores de entrada e executa a mesma operação em cada um deles. Algo parecido com o arquivo ~/bin/trash :

#!/usr/bin/env bash

for f in "$@"
do 
    mv f ~/trashcan
done

que eu pretendo usar assim

$touch 2.txt 3.txt 4.txt  # create demo files
$trash *.txt

Conforme escrito, ao executar isso no Git Bash (no Windows), recebo o seguinte erro:

bash: syntax error near unexpected token '2.txt'
    
por Steven C. Howell 28.02.2018 / 22:33

3 respostas

4

Tente:

#!/usr/bin/env bash

for f; do 
    mv "$f" ~/trashcan
done
  • o sigil $ 'é obrigatório para chamar uma variável declarada ( $f )
  • não precisa for f in "$@" aqui
por 28.02.2018 / 22:44
3

No seu código, você esqueceu o $ na frente de f no corpo do loop. Isso também deve ser citado corretamente como "$f" para suportar nomes de arquivos com espaços, etc. Não sei se essa é a causa da sua mensagem de erro (e não vejo nada no código que possa causar a exibição desse erro). O erro que eu esperaria é No such file or directory ao tentar mover um f não existente.

Para um pequeno utilitário como esse, você poderia transformá-lo em uma função shell no seu arquivo ~/.bashrc :

trash () {
    local trashcan="$HOME/trashcan"
    mkdir -p "$trashcan"

    mv -f -v "$@" "$trashcan"
}

Esta função garante que a pasta da lixeira realmente exista antes de mover as coisas para ela. Ele também executará a movimentação com detalhes, exibindo os nomes das coisas que são movidas.

Não há necessidade de iterar aqui, pois "$@" será expandido corretamente para os nomes dados à função na linha de comando.

A única razão pela qual posso ver por querer realmente iterar sobre os nomes é se você deseja ter certeza de que o destino de mv não existe antes de executar a movimentação (para que as coisas na lixeira não sejam exibidas sobrescritos por novos itens). Com mv do GNU coreutils, você pode fazer isso automaticamente com algo como

mv -f -v --backup=numbered "$@" "$trashcan"

Com o não-GNU mv você pode querer aquele loop (isto está substituindo o mv na função de shell acima):

local trash_ext="$RANDOM"

for name; do
    while [ -e "$trashcan/${name##*/}.$trash_ext" ]; do
        trash_ext="$RANDOM"
    done

    mv -f -v "$name" "$trashcan/${name##*/}.$trash_ext"
done

Esta é apenas uma maneira rápida e suja de criar um nome exclusivo, adicionando um número aleatório após o nome do arquivo. A coisa ${name##*/} expandirá para o nome da base (a parte do nome do caminho do nome do caminho) de $name e poderá ser substituída por $( basename "$name" ) .

    
por 28.02.2018 / 23:08
-2
while read -r a
do
 for i in $a
 {
   mv -f $a ~/trashcan
  }
done < *.txt

com requisito: cada nome de arquivo em arquivos * .txt é separado por espaço ou nova linha

    
por 01.03.2018 / 04:39