Eu tenho as seguintes instruções if-else que verificam se o sinalizador i foi adicionado ao comando e, em caso afirmativo, grava no arquivo a partir do stdin:
29 if [ $inplace -eq 1 ]; then
30 tmp_file=$(mktemp)
31 awk -v num="^$number" -v col="$column" -v value="$value" -F ',' \
32 'BEGIN{OFS=FS}{ if ($0 ~ num) { $col=value; print } else print}' "$file" > "$tmp_file"
33 mv "$tmp_file" "$file"
34 else
35 awk -v num="^$number" -v col="$column" -v value="$value" -F ',' \
36 'BEGIN{OFS=FS}{ if ($0 ~ num) { $col=value; print } else print}' "$file"
37 fi
mas estou recebendo o seguinte erro:
mv: cannot move '/tmp/tmp.ahALZC2Hgh' to '': No such file or directory
o que significa que $file está vazio e isso faz sentido para mim porque li em algum lugar que stdin só pode ser usado uma vez e está sendo usado pelo awk cmd acima
alguém sabe como manter o valor? (sem fazer algo como: var=$(cat), pois ouvi dizer que isso era uma prática ruim?)
ou se for uma má ideia porque não deveria ser implementada, também funciona!
o comando que executa o arquivo e recebe o erro é:
cat data.csv | ./update.sh -n 444 -c 2 -v "Alex" -i
e o sinalizador i serve para o usuário indicar que deseja que alterações sejam feitas no arquivo original; nesse caso, a variável $inplace é definida como 1 no seguinte caso, while loop:
3 while getopts f:n:c:v:i opt; do
4 case $opt in
5 f) file="$OPTARG";;
6 n) number="$OPTARG";;
7 c) column="$OPTARG";;
8 v) value="$OPTARG";;
9 i) inplace=1;;
10 *) printf>&2 '%s\n' "Usage: $0 [-f file] [-n number] [-c column] [-v value]";;
11 esac
12 done
aqui está o script completo:
#!/bin/bash
while getopts f:n:c:v:i opt; do
case $opt in
f) file="$OPTARG";;
n) number="$OPTARG";;
c) column="$OPTARG";;
v) value="$OPTARG";;
i) inplace=1;;
*) printf>&2 '%s\n' "Usage: $0 [-f file] [-n number] [-c column] [-v value]";;
esac
done
if [ -z "$column" ]; then
echo "Please specify a column number with -c." >&2
exit 1
elif [ -z "$number" ]; then
echo "Please specify a phone number to filter by via -n" >&2
exit 1
elif [ -z "$value" ]; then
echo "Please specify the new value via -v" >&2
exit 1
elif [ "$column" -gt 4 ] || [ "$column" -lt 1 ]; then
echo "this script can only handle cols1-4. for group editing, try ./groups.sh" >&2
exit 1
fi
if [ $inplace -eq 1 ]; then
tmp_file=$(mktemp)
awk -v num="^$number" -v col="$column" -v value="$value" -F ',' \
'BEGIN{OFS=FS}{ if ($0 ~ num) { $col=value; print } else print}' "$file" > "$tmp_file"
mv "$tmp_file" "$file"
else
awk -v num="^$number" -v col="$column" -v value="$value" -F ',' \
'BEGIN{OFS=FS}{ if ($0 ~ num) { $col=value; print } else print}' "$file"
fi
exit 0
Veja os comentários que você recebeu e tente isto (não testado) como ponto de partida:
Você deve fazer mais validações nos argumentos de opção para garantir, por exemplo, que valores como esse
column
que você espera que sejam um número natural sejam realmente números naturais.