Unix bash / ksh: Seleção do primeiro caractere não espacial do arquivo da linha específica

1

Eu tenho o arquivo file1.txt cujo conteúdo é o seguinte:

Date List
-----------
    Quarter Date
         Year Date
             Month Date

Agora quero ler os elementos não espaciais de cada linha de arquivo e gravar em uma variável. Por exemplo, para a variável da linha 2, deve conter Quarter Year somente após a remoção do espaço.

Eu tentei:

tail -1 file1.txt > variable1

Mas isso não funciona.

    
por Aman 12.06.2015 / 10:41

4 respostas

7

Usando sed :

variable1="$(< inputfile sed -n '3s/ *//p')"
  • variable1="$([...])" : executa o comando [...] em uma subshell e atribui sua saída à variável $variable
  • < inputfile : redireciona o conteúdo de inputfile para sed ' stdin
  • -n : suprime a saída

% de colapso do comandosed :

  • 3 : afirma para executar o seguinte comando apenas na terceira linha de entrada
  • s : afirma para executar uma substituição
  • / : inicia o padrão de pesquisa
  • * : corresponde a zero ou mais caracteres
  • / : interrompe o padrão de pesquisa / inicia a string de substituição
  • / : interrompe a string de substituição (por isso, na verdade substitui nada) / inicia os modificadores
  • p : imprime apenas as linhas onde a substituição foi bem sucedida
por 12.06.2015 / 11:03
5

Primeiro, leia a linha desejada em uma variável (linha 3 no exemplo):

var=$(sed -n '3p' file1.txt)

O comando sed imprime ( p ) a terceira linha do arquivo. A faixa dos espaços principais usando a substituição de parâmetros :

echo "${var#"${var%%[![:space:]]*}"}"

A substituição interna significa remover tudo exceto os espaços à esquerda. A substituição externa remove esses espaços no começo da linha.

A saída é:

Quarter Date
    
por 12.06.2015 / 11:10
4

tail -1 file1.txt > variable1 escreve no arquivo variable1 .

Use a substituição de comando (bash.info 3.5.4, POSIX sh):

variable1="$(tail -1 file1.txt)"

Por exemplo, minha versão do tail do GNU no cygwin não tem a opção -1 . Em vez disso, eu uso sed :

# EREGEX: Replace all whitespace at beginning of line
# NOTE: BSD sed uses a different flag to enable EREGEX, -E.
# EDIT: Dropped -r. \s is already included in BRE.
#       Thanks to kos for pointing that out.
# EDIT: Use POSIX [:space:] instead of Perl \s.
variable1="$(sed -e 's/^[[:space:]]*//g' < file1.txt)"

Combinado com a seleção de linha:

# EDIT: limit the [s]ubstitude operation to the 4th line only, and
#       [p]rint directly from s.
variable1="$(sed -ne '4s/^[[:space:]]*//p' < file1.txt)"
    
por 12.06.2015 / 11:07
3

Com ksh / zsh / bash :

IFS=' ' read -r variable < <(tail -n 1 file)

read retira os caracteres iniciais e posteriores se houver espaço em IFS (que é por padrão junto com aba e nova linha).

Você também pode fazer:

while IFS=' ' read -r variable <&3; do
  something with "$variable"
done 3< file

Para processar o arquivo linha a linha ( embora não seja normalmente o caminho a seguir em shells ) com $variable mantendo o conteúdo da linha atual com os espaços iniciais e finais removidos.

    
por 12.06.2015 / 12:52