Estou tentando executar um comando awk com base no fato de um arquivo ter sido fornecido ou não como argumento e, se não, apenas executá-lo em stdin assim:
38 for index in "${line_numbers[@]}"; do
39 if [ -n "$file" ]; then
40 echo "hi"
41 cat "$file" | awk -v idx="$index" -v col="$column" -v value="$value" -F ',' '{if (idx==NR) {for(i=1;i<=NF;i++) { if (i==col) $i=value; printf("%s%s", $i, (i==NF ? "\n":FS))}}}'
42 else
43 echo "bye"
44 awk -v col="$column" -v idx="$index" -v value="$value" -F ',' '{if (idx==NR) {for(i=1;i<=NF;i++) {if (i==col) $i =value; printf("%s%d%s", $i, i, (i==NF ? "\n":FS))}}}'
45 fi
46 done
o arquivo é lido usando getopts (mas isso não é importante, pois estou contando com stdin para o seguinte, mas pensei em mencionar este código):
3 file=""
4 unset -v number column value
5 cmd="echo"
6
7 while getopts f:n:c:v: opt; do
8 case $opt in
9 f) file="$OPTARG";;
10 n) number="$OPTARG";;
11 c) column="$OPTARG";;
12 v) value="$OPTARG";;
13 *) printf>&2 '%s\n' "Usage: $0 [-f file] [-n number] [-c column] [-v value]";;
14 esac
15 done
Mas a saída do loop for é apenas "tchau" seguido de "tchau" (ele é executado duas vezes, o que é esperado com base nos dados), mas o comando awk não é executado.
Fiquei com a impressão de que stdin é o padrão usado pelos comandos, mas o comando awk não está executando nada, embora deva gerar algo como eu testei.
Alguma ideia de por que o comando awk no else
bloco não está em execução?
O comando que estou executando é:
cat data.csv | ./update.sh -n 444 -c 2 -v " Alex"
e os dados são:
444-555-7777, Max,Weaver, personal:friend:musician
111-222-6665, Craig,Kowalick,office:friend
888-797-2345,Tom, O’Brien, personal:family:musician:midnightsociety
444433443,fgdfg,gdfg,fdgdfgf:test:test:test2
então a saída deve ser:
444-555-7777, Alex,Weaver, personal:friend:musician
444433443, Alex,gdfg,fdgdfgf:test:test:test2
Editar: aparentemente algo está consumindo stdin e, embora eu não consiga entrar no modo de depuração (o vim está me dizendo que não reconhece: set -x), aqui está meu script:
#!/bin/bash
my_stdin=$(cat)
file=""
unset -v number column value
cmd="echo"
while getopts f:n:c:v: opt; do
case $opt in
f) file="$OPTARG";;
n) number="$OPTARG";;
c) column="$OPTARG";;
v) value="$OPTARG";;
*) printf>&2 '%s\n' "Usage: $0 [-f file] [-n number] [-c column] [-v value]";;
esac
done
shift $((OPTIND-1))
if [ "$column" -gt 4 ] || [ "$column" -lt 1 ]; then
echo "this script can only handle cols1-4. for group editing, try ./groups.sh"
exit 1
fi
declare -a line_numbers
grep_output=$(grep -n "$number" <<< "$my_stdin" | cut -d: -f1)
if [ -n "$file" ]; then
grep_output="$(cat "$file" | grep -n "$number" | cut -d: -f1)"
fi
echo "$grep_output"
IFS=$'\n' read -d '' -ra line_numbers <<< "$grep_output"
for index in "${line_numbers[@]}"; do
if [ -n "$file" ]; then
echo "hi"
cat "$file" | awk -v idx="$index" -v col="$column" -v value="$value" -F ',' '{if (idx==NR) {for(i=1;i<=NF;i++) {if (i==col) $i=value; printf("%s%s", $i, (i==NF ? "\n":FS))}}}' "${@:--}"
else
awk -v col="$column" -v idx="$index" -v value="$value" -F ',' '{if (idx==NR) {for(i=1;i<=NF;i++) {if (i==col) $i=value; printf("%s%s", $i, (i==NF ? "\n":FS))}}}' <<< "$my_stdin"
fi
done
echo
exit 0
Esta linha consome seu stdin:
Então, quando você chega ao
awk
ponto, não há mais nada para consumir. Não consigo descobrir o que o seu script deve fazer, já que a saída que você fornece não parece vir da entrada, mas uma maneira simples de fazer o awk funcionar em um arquivo, se presente, ou stdin, se não, é usar um variável:Para ilustrar, considere este script simples:
Se você executá-lo com um argumento,
$1
será definido eawk
tentará lê-lo:Se você executá-lo sem argumento, ele lê STDIN:
Agora, acho que o que você quer fazer é alterar o valor da coluna fornecida em qualquer linha que comece com o número fornecido. Nesse caso, você poderia simplificar todo o seu script para:
Agora você pode executar isso conforme necessário:
Observe que você
grep
corresponderia444
a qualquer lugar do arquivo. Se é isso que você deseja, usenum="$number"
em vez denum="^$number"
.