Eu tenho um arquivo como abaixo:
line1
line2
line3
E eu quero obter:
prefixline1
prefixline2
prefixline3
Eu poderia escrever um script Ruby, mas é melhor se eu não precisar.
prefix
irá conter /
. É um caminho, /opt/workdir/
por exemplo.
Eu tenho um arquivo como abaixo:
line1
line2
line3
E eu quero obter:
prefixline1
prefixline2
prefixline3
Eu poderia escrever um script Ruby, mas é melhor se eu não precisar.
prefix
irá conter /
. É um caminho, /opt/workdir/
por exemplo.
Respostas:
# If you want to edit the file in-place
sed -i -e 's/^/prefix/' file
# If you want to create a new file
sed -e 's/^/prefix/' file > file.new
Se prefix
contiver /
, você poderá usar qualquer outro caractere que não esteja prefix
ou escapar do /
, para que o sed
comando se torne
's#^#/opt/workdir#'
# or
's/^/\/opt\/workdir/'
sed
em um pipeline, por exemplo foo | sed -e 's/^/x /' | bar
.
sed -e '2,$s/^/prefix/'
.
sed -e 's/$/postfix/' file
se você deseja adicionar uma sequência ao final de cada linha.
awk '$0="prefix"$0' file > new_file
Com Perl (substituição no local):
perl -pi 's/^/prefix/' file
prtinf "$VARIABLE\n" | awk '$0="prefix"$0'
awk
relatórios awk: out of memory in readrec 1 source line number 1
, mas a solução é sed
concluída com êxito.
Você pode usar o Vim no modo Ex:
ex -sc '%s/^/prefix/|x' file
%
selecione todas as linhas
s
substituir
x
salvar e fechar
:%s/^/prefix/
, uma vez que esta estratégia acaba por ser útil em muitas situações
Se você tem Perl:
perl -pe 's/^/PREFIX/' input.file
Usando o shell:
#!/bin/bash
prefix="something"
file="file"
while read -r line
do
echo "${prefix}$line"
done <$file > newfile
mv newfile $file
Aqui está uma solução oneliner altamente legível usando o ts
comando de moreutils
$ cat file | ts prefix | tr -d ' '
E como é derivado passo a passo:
# Step 0. create the file
$ cat file
line1
line2
line3
# Step 1. add prefix to the beginning of each line
$ cat file | ts prefix
prefix line1
prefix line2
prefix line3
# Step 2. remove spaces in the middle
$ cat file | ts prefix | tr -d ' '
prefixline1
prefixline2
prefixline3
Embora eu não ache que o pierr tenha essa preocupação, eu precisava de uma solução que não atrasasse a saída do "final" ativo de um arquivo, pois queria monitorar vários logs de alerta simultaneamente, prefixando cada linha com o nome do respectivo log .
Infelizmente, sed, cut, etc. introduziram muito buffer e me impediram de ver as linhas mais atuais. A sugestão de Steven Penny de usar a -s
opção de nl
era intrigante, e os testes provaram que não introduziam o buffer indesejado que me preocupava.
Porém, houve alguns problemas com o uso nl
, relacionados ao desejo de remover os números de linhas indesejados (mesmo que você não se importe com a estética dele, pode haver casos em que o uso de colunas extras seria indesejável). Primeiro, usar "recortar" para eliminar os números reintroduz o problema do buffer, destruindo a solução. Segundo, o uso de "-w1" não ajuda, pois isso NÃO restringe o número da linha a uma única coluna - apenas aumenta à medida que são necessários mais dígitos.
Não é bonito se você deseja capturar isso em outro lugar, mas como é exatamente isso que eu não precisava fazer (tudo estava sendo gravado nos arquivos de log, eu só queria assistir vários de uma vez em tempo real), o melhor Uma maneira de perder os números de linha e ter apenas meu prefixo era iniciar a -s
sequência com um retorno de carro (CR ou ^ M ou Ctrl-M). Então, por exemplo:
#!/bin/ksh
# Monitor the widget, framas, and dweezil
# log files until the operator hits <enter>
# to end monitoring.
PGRP=$$
for LOGFILE in widget framas dweezil
do
(
tail -f $LOGFILE 2>&1 |
nl -s"^M${LOGFILE}> "
) &
sleep 1
done
read KILLEM
kill -- -${PGRP}
-u
opção sed para evitar o buffer.
Usando ed:
ed infile <<'EOE'
,s/^/prefix/
wq
EOE
Isso substitui, para cada linha ( ,
), o início da linha ( ^
) por prefix
. wq
salva e sai.
Se a sequência de substituição contiver uma barra, podemos usar um delimitador diferente para s
:
ed infile <<'EOE'
,s#^#/opt/workdir/#
wq
EOE
Eu citei o delimitador here-doc EOE
("end of ed") para impedir a expansão de parâmetros. Neste exemplo, ele também não funcionaria entre aspas, mas é uma boa prática evitar surpresas se você tiver um $
em seu script ed.
Você também pode conseguir isso usando a técnica de backreference
sed -i.bak 's/\(.*\)/prefix\1/' foo.txt
Você também pode usar com o awk como este
awk '{print "prefix"$0}' foo.txt > tmp && mv tmp foo.txt
Aqui está um exemplo embrulhado usando a sed
abordagem de esta resposta :
$ cat /path/to/some/file | prefix_lines "WOW: "
WOW: some text
WOW: another line
WOW: more text
function show_help()
{
IT=$(CAT <<EOF
Usage: PREFIX {FILE}
e.g.
cat /path/to/file | prefix_lines "WOW: "
WOW: some text
WOW: another line
WOW: more text
)
echo "$IT"
exit
}
# Require a prefix
if [ -z "$1" ]
then
show_help
fi
# Check if input is from stdin or a file
FILE=$2
if [ -z "$2" ]
then
# If no stdin exists
if [ -t 0 ]; then
show_help
fi
FILE=/dev/stdin
fi
# Now prefix the output
PREFIX=$1
sed -e "s/^/$PREFIX/" $FILE
PREFIX
houver caracteres especiais para sed como uma barra.
prefix_lines \*
Para as pessoas nos sistemas BSD / OSX, existe um utilitário chamado lam
, abreviação de laminado. lam -s prefix file
fará o que você quiser. Eu o uso em dutos, por exemplo:
find -type f -exec lam -s "{}: " "{}" \; | fzf
... que encontrará todos os arquivos, exec lam em cada um deles, dando a cada arquivo um prefixo de seu próprio nome de arquivo. (E bombeie a saída para fzf para pesquisa.)
sed
para tarefas leves como esta. Se "prefixo" é conhecido, é muito fácil escolher um caractere que não seja "prefixo".