Você pode usar o awk:
awk '/^\*/ {sub(/\*/, ++i)} 1' <<END
A list
* one
* two
Blah
* three
END
A list
1 one
2 two
Blah
3 three
Usando sed
, como posso substituir as linhas que começam com uma estrela e substituí-las por números a partir de 1?
Eu preciso substituir o (*) no punho de uma lista por números usando sed por exemplo >
este arquivo contém uma lista
*linux
*computers
*labs
*questions
para > > > >
este arquivo contém uma lista
1 linux
2 computers
3 labs
4 questions
Eu tentei usar
sed -e 's/*//' file.in > file.out | sed -i = file.out
Você pode usar o awk:
awk '/^\*/ {sub(/\*/, ++i)} 1' <<END
A list
* one
* two
Blah
* three
END
A list
1 one
2 two
Blah
3 three
Você pode reproduzir alguns truques - as primeiras linhas numéricas com *
somente, depois, remover *
e spaces
se você quiser
nl -bp^[*] file | sed 's/^\s*\|\s*\*//g'
{ tr -s \n |
sed =|
sed '$!N;s/\n./ /'
} <<\INPUT
*linux
*computers
*labs
*questions
INPUT
1 linux
2 computers
3 labs
4 questions
nl
é o mais óbvio, mas sed
pode contar linhas. sed
não está sozinho a esse respeito:
sh <<HD
$(sed -n 's/^\*\(.*\)/echo "$LINENO "/p' <infile)
HD
... ou ...
sed -n "s/..*/OUT='&'/p" <infile |
PS1='${LINENO#0} ${OUT#?}${IFS#??}' dash -i
... ambos imprimem o mesmo que antes (mesmo que seja um pouco bobo) . Eu uso dash
explicitamente aqui, porque, por padrão, ele não ativa nenhum leitor de terminal readline
. Se dash
for seu sh
, você pode usar apenas sh
, mas se bash
estiver vinculado a sh
, será necessário usar --noediting
para o segundo exemplo para evitar a impressão de OUT=...
de material para o terminal também.
E, na verdade, para o seu exemplo de exemplo simples, tudo pode ser feito com nl
e tr
:
tr -d \* <<\INPUT| nl -s ' ' -w1 -nln
*linux
*computers
*labs
*questions
INPUT
1 linux
2 computers
3 labs
4 questions
Eu usaria o perl em vez disso. A sintaxe para isso é muito semelhante a sed
's:
perl -pe 's/^\*/$c++/e' file
Ou, para começar a partir de 1:
perl -pe 's/^\*/++$c/e' file
E para editar o arquivo original:
perl -i -pe 's/^\*/++$c/e' file
Não consigo encontrar uma solução que use apenas sed
, mas isso chega perto. Ele usa apenas sed
, recursos internos do shell e cmp
e mv
. Com algum esforço e um shell moderno, você pode reescrever isso para manter o conteúdo do arquivo nas variáveis do shell e não precisar usar cmp
ou mv
.
#!/bin/sh
if test $# -ne 1
then
echo usage: $0 file
exit 1
fi
num=1 # start numbering at 1
infile="$1"
outfile="$1.out"
mv "$infile" "$outfile" # set up so initial cmp always fails
while ! cmp -s "$infile" "$outfile" # repeat the sed until no more ^* can be found
do
mv "$outfile" "$infile"
# replace the first occurrence of ^* with a number and a space
sed '0,/^\*/s//'$num' /' "$infile" > "$outfile"
num=$(expr $num + 1)
done
rm "$outfile"
teste:
$ cat i
first line
*second
*third
fourth
*fifth
$ ./change i
$ cat i
first line
1 second
2 third
fourth
3 fifth
sed
não pode fazer cálculos, portanto, isso não é possível de maneira útil.
Tags text-processing sed