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