Знайсці і замяніць - просты Баш скрыпт

Я не вельмі знаёмы з Баш сцэнарыяў, але выкажам здагадку, што ў мяне ёсць файл textfile.txt з імёнамі і пошты, якія складаюцца з некалькіх радкоў з некалькімі нумарамі уваходжанняў гэтых мадэляў:

[email protected];othername.othersurname;[email protected];othername.othersurname;[email protected];...

Я хацеў бы, каб здушыць з гэтага спісу ўсіх запісаў, якія не зьяўляюцца лістом. Таму выкажам здагадку, што мой выкананы файл file.sh і што я бягу ш file.sh textfile.txt

#!/bin/bash

if [–f $1];

awk -F ";" '{//here comes what I am looking for
}' $1

else 

echo "there is no such file"

fi

Я не ведаю, з якім сінтаксісам я магу захапіць апошнюю адфільтраваную запіс (каб праверыць, калі ёсць не @ знак, каб выдаліць яго з спісу). Я спрабаваў Google гэта, але без поспеху

0
Да точно, я спрабую выправіць файл ў месцы, выдаленне ўсіх не-адрасы электроннай пошты
дададзена аўтар epsilones, крыніца
Да точно, я спрабую выправіць файл ў месцы, выдаленне ўсіх не-адрасы электроннай пошты
дададзена аўтар epsilones, крыніца
Да точно, я спрабую выправіць файл ў месцы, выдаленне ўсіх не-адрасы электроннай пошты
дададзена аўтар epsilones, крыніца
Што менавіта вы спрабуеце зрабіць: адрэдагаваць файл на месцы, выдаленне ўсіх не па электроннай пошце-адрас? Паказаць усе адрасы электроннай пошты ў файле? Нешта яшчэ?
дададзена аўтар Markku K., крыніца
Што менавіта вы спрабуеце зрабіць: адрэдагаваць файл на месцы, выдаленне ўсіх не па электроннай пошце-адрас? Паказаць усе адрасы электроннай пошты ў файле? Нешта яшчэ?
дададзена аўтар Markku K., крыніца

7 адказы

Я не ведаю, AWK прабачце, але вы можаце зрабіць гэта з Perl

perl -p -e 's/;[^;@]+;/;/g'

Але ёсць адна памылка ў ім, ён будзе не хапаць яго, калі першая або апошняя запіс у радку з'яўляецца несапраўднай электроннай пошты. Для таго, каб вырашыць гэтыя правільна вам трэба падзяліць/чэк/далучыцца, які пачынае заблытацца ў адным радку

perl -p -e 'join(";",grep(/@/,split(";",$_)))'

Edit: Oops, sorry, mistake when cutting over from ideone to command line. I was missing the assignment back to $_, which is what is printed by the -p

perl -p -e '$_ = join(";",grep(/@/,split(";",$_)))'
  • split(";",$_) splits the current line ($_) into an array of elements using the ; as the delimiter.
  • grep(/@/,...) then only returns the elements of the array which contain an @. This was my simplistic test for a valid email address. If you want to be more thourough you could use a more rigorous regexp for email address. Maybe /^[^\[email protected]][email protected][^\[email protected]]+\.[^\[email protected]]+$/
  • Then the join(";"...) recombines the valid email addresses into a ; delimited string.
1
дададзена
дзякуй, але гэта не працуе ...
дададзена аўтар epsilones, крыніца
Дарэчы вы маглі б растлумачыць, як азначае гэты сінтаксіс: Grep (/ @ /, раскол ( ";", $ _))
дададзена аўтар epsilones, крыніца

Я не ведаю, AWK прабачце, але вы можаце зрабіць гэта з Perl

perl -p -e 's/;[^;@]+;/;/g'

Але ёсць адна памылка ў ім, ён будзе не хапаць яго, калі першая або апошняя запіс у радку з'яўляецца несапраўднай электроннай пошты. Для таго, каб вырашыць гэтыя правільна вам трэба падзяліць/чэк/далучыцца, які пачынае заблытацца ў адным радку

perl -p -e 'join(";",grep(/@/,split(";",$_)))'

Edit: Oops, sorry, mistake when cutting over from ideone to command line. I was missing the assignment back to $_, which is what is printed by the -p

perl -p -e '$_ = join(";",grep(/@/,split(";",$_)))'
  • split(";",$_) splits the current line ($_) into an array of elements using the ; as the delimiter.
  • grep(/@/,...) then only returns the elements of the array which contain an @. This was my simplistic test for a valid email address. If you want to be more thourough you could use a more rigorous regexp for email address. Maybe /^[^\[email protected]][email protected][^\[email protected]]+\.[^\[email protected]]+$/
  • Then the join(";"...) recombines the valid email addresses into a ; delimited string.
1
дададзена
дзякуй, але гэта не працуе ...
дададзена аўтар epsilones, крыніца
Дарэчы вы маглі б растлумачыць, як азначае гэты сінтаксіс: Grep (/ @ /, раскол ( ";", $ _))
дададзена аўтар epsilones, крыніца

Я не ведаю, AWK прабачце, але вы можаце зрабіць гэта з Perl

perl -p -e 's/;[^;@]+;/;/g'

Але ёсць адна памылка ў ім, ён будзе не хапаць яго, калі першая або апошняя запіс у радку з'яўляецца несапраўднай электроннай пошты. Для таго, каб вырашыць гэтыя правільна вам трэба падзяліць/чэк/далучыцца, які пачынае заблытацца ў адным радку

perl -p -e 'join(";",grep(/@/,split(";",$_)))'

Edit: Oops, sorry, mistake when cutting over from ideone to command line. I was missing the assignment back to $_, which is what is printed by the -p

perl -p -e '$_ = join(";",grep(/@/,split(";",$_)))'
  • split(";",$_) splits the current line ($_) into an array of elements using the ; as the delimiter.
  • grep(/@/,...) then only returns the elements of the array which contain an @. This was my simplistic test for a valid email address. If you want to be more thourough you could use a more rigorous regexp for email address. Maybe /^[^\[email protected]][email protected][^\[email protected]]+\.[^\[email protected]]+$/
  • Then the join(";"...) recombines the valid email addresses into a ; delimited string.
1
дададзена
дзякуй, але гэта не працуе ...
дададзена аўтар epsilones, крыніца
Дарэчы вы маглі б растлумачыць, як азначае гэты сінтаксіс: Grep (/ @ /, раскол ( ";", $ _))
дададзена аўтар epsilones, крыніца

Вось адзін са спосабаў зрабіць гэта ў Баш скрыпт без AWK або Perl ...

origfile=$1
copyfile=`mktemp`

for email in `sed 's/;/\n/g' $origfile | grep "@"`; do
    printf "$email;" >> $copyfile
done

#you may want to check that $copyfile is valid in some way before the next step
mv $copyfile $origfile
1
дададзена

Вось адзін са спосабаў зрабіць гэта ў Баш скрыпт без AWK або Perl ...

origfile=$1
copyfile=`mktemp`

for email in `sed 's/;/\n/g' $origfile | grep "@"`; do
    printf "$email;" >> $copyfile
done

#you may want to check that $copyfile is valid in some way before the next step
mv $copyfile $origfile
1
дададзена

Вось адзін са спосабаў зрабіць гэта ў Баш скрыпт без AWK або Perl ...

origfile=$1
copyfile=`mktemp`

for email in `sed 's/;/\n/g' $origfile | grep "@"`; do
    printf "$email;" >> $copyfile
done

#you may want to check that $copyfile is valid in some way before the next step
mv $copyfile $origfile
1
дададзена

Тут элемент AWK рашэнне. Але толькі AWK , так што я не прапаную, каб уключыць яго ў сцэнар абалонкі. Ён павінен працаваць запусціць яго з каманднага радка:

awk '

    ## Split (in input) and join (in output) fields with colon.
    BEGIN { FS = OFS = ";" }
    {   
        ## Traverse all fields and delete those that do not contain one "@".
        for ( i = 1; i <= NF; i++ ) { if ( index( $i, "@" ) == 0 ) { $i = "" } } 

        ## There will be some consecutive colons between those fields deleted.
        ## Keep only one.
        gsub( /;{2,}/, ";" )

        ## Print the whole line only with emails.
        print
    }   

' infile

З вашым прыкладам лініяй, гэта дае:

[email protected];[email protected];[email protected]
0
дададзена