Solução awk curta:
awk -F'#' 'NF{ print ($1 != "" ? $1 : $2) }' file
A saída:
abc
nrt
clb1aX
amd
O arquivo ( myfile.txt ) contém dados da seguinte forma:
abc#ab1=23
nrt#
#clb1aX
amd#322
Saída desejada:
abc
nrt
clb1ax
amd
Eu poderia fazer assim,
for i in 'cat myfile.txt'
do
s1='echo $i | cut -d'#' -f1';
s2='echo $i | cut -d'#' -f2';
if [ "$s1" == "" ]; then
echo "$s2"
else
echo "$s1"
fi;
done;
Mas há alguma maneira de fazer isso sem usar for e if , como usar awk ou sed ou cut ou algo mais em uma única linha?
sed -i "/^#/ { s/#\(.*\)//; b }
s/#.*//" myfile.txt
Ele pode ser unido em uma linha adicionando o ; após o } , mas será mais difícil lê-lo assim.
sed -i Mantenha as alterações no arquivo, não as grave em stdout .
/^#/ - Quando sed está posicionado na linha que começa com # .
s/#\(.*\)// - Substitua a primeira ocorrência de #[everything] por [everything] .
b - Interrompa o trabalho na linha atual e comece a trabalhar no próximo.
(Impede que o comando s/#.*// seja executado).
s/#.*// - Remove a primeira ocorrência de #[everything] .
(Isso funcionará para todas as linhas, a menos que o comando anterior b tenha saído antes.)
myfile.txt Arquivo no qual sed será executado.
E se você não tivesse campos com valor ou não fosse apenas na segunda coluna? então você precisaria.
awk -F'#' '{for(i=1; i<=NF; i++) if ($i != "") {print $i; break} }' infile
Dada abaixo da amostra:
abc#asd=123 nrt# #clsdX #### ###here acn#123
fornecerá a saída:
abc
nrt
clsdX
here
acn
Ou usando sed e cut :
cut -d'#' -f1 <(sed 's/^#\+//; /^$/d' infile )
s/^#\+// remove os hashes principais # (ocorreu uma ou mais vezes) /^$/d remove a linha vazia produzida acima, em que uma linha era toda hashes ##### ou remove linhas vazias no arquivo, se houvesse alguma. cut -d'#' -f1 imprime o primeiro campo -f1 quando fileds são delimitados por um hash -d'#' Ou sed apenas:
sed 's/^#\+//; /^$/d; s/^\([^#]*\)#.*//' infile
s/^\([^#]*\)#.*// captura um grupo de partida começando do início da linha para qualquer coisa até que um primeiro hash seja visto e apenas imprima em resultado e ignore o restante. Usando perl - assumindo apenas # na entrada como dado na amostra
$ perl -pe 's/[^#]\K#.*|^#//' ip.txt
abc
nrt
clb1aX
amd
[^#]\K#.* para excluir todos os caracteres da primeira ocorrência de # se houver um caractere não # anterior a |^# caso contrário, remova # do início da linha
Mesma coisa com sed
$ sed 's/\([^#]\)#.*\|^#//' ip.txt
abc
nrt
clb1aX
amd
Outro sed
sed 's/^#*\([^#]*\).*//' infile
Se você deseja remover linhas apenas com ####
sed 's/^#*\([^#]*\).*//;/^$/d' infile
awk '{sub(/^#/,"")sub(/#/," &");print $1}' file
abc
nrt
clb1aX
amd
Tags awk shell-script cut