É possível executar um comando em uma string armazenada dentro de uma variável?

É possível executar um comando em uma string armazenada dentro de uma variável?

Olá, estou tentando executar o seguinte código. Armazenei uma string dentro da variável DATE que está no formato AAAA/MM/DD. Estou tentando extrair o ano usando o comando cut. Recebo um erro informando que não é um arquivo ou diretório. Existe alguma modificação que eu possa fazer ou uma maneira diferente de fazer isso?

for file in ~/filesToSort/*
do

   DATE=$(head -1 $file | tr "-" "/")
   echo "${DATE}"
   YYYY=$(cut -c1-4 accounts $DATE)
   #echo "${YYYY}"
done

Obrigado

Responder1

O cututilitário lê dados de seu fluxo de entrada padrão, mas não opera em strings fornecidas como argumentos.

Para usar cut, portanto, você precisa passar os dados na entrada padrão:

YYYY=$( printf '%s\n' "$DATE" | cut -d '/' -f 1 )

No entanto, isso seria muito lento em um loop. Em vez disso, use uma substituição de parâmetro integrada para excluir tudo após o primeiro /na $DATEstring:

YYYY=${DATE%%/*}

Isso remove a string de sufixo mais longa $DATEque corresponde ao padrão de shell /*. Se a string for 2021/10/21, então isso retorna 2021.

Para obter os primeiros quatro caracteres de cada arquivo em um diretório (que é a essência do que euacreditarseu código atual está tentando fazer), você poderia usar sedassim:

for name in "$HOME"/filesToSort/*; do
    sed -e 's/\(....\).*/\1/' -e q "$name"
done

Ele lê a primeira linha de cada arquivo, substitui o conteúdo da linha pelos primeiros quatro caracteres da linha e sai após enviar o resultado para o terminal.

Responder2

Se o seu shell suportar, você pode usar Here Strings ( <<<) para isso. De man bash:

Here Strings
       A variant of here documents, the format is:

              [n]<<<word

       The word undergoes tilde expansion, parameter and variable  expansion,
       command  substitution, arithmetic expansion, and quote removal.  Path‐
       name expansion and word splitting are not performed.   The  result  is
       supplied  as  a single string, with a newline appended, to the command
       on its standard input (or file descriptor n if n is specified).

No seu caso, você faria:

for file in ~/filesToSort/*
do

   date=$(head -1 "$file" | tr "-" "/")
   echo "${DATE}"
   yyy=$(cut -c1-4 <<< "$date")
   echo "$yyy"
done

Responder3

Mais uma maneira de usar o bom e velhoawk

for file in *; do
    awk -F'-' 'NR==1 {print $1}' $file
done
  • -F '-'diz ao awk para usar o -como delimitador
  • NR==1diga ao awk para ler apenas a primeira linha de cada arquivo
  • {print $1}imprima apenas o primeiro campo separado pelo delimitador

informação relacionada