Jeg har brug for hjælp til at finde ud af, hvordan man bruger kommandoen sed til kun at vise den første kolonne og den sidste kolonne i en tekstfil. Her er hvad jeg hidtil har til kolonne 1:
cat logfile | sed "s/\|/ /"|awk "{print $1}" 
Mit svage forsøg på at få den sidste kolonne til at vise også var:
cat logfile | sed "s/\|/ /"|awk "{print $1}{print $8}" 
Dette tager dog den første kolonne og sidste kolonne og fletter dem sammen i en liste. Er der en måde at udskrive den første kolonne og sidste kolonne tydeligt med sed- og awk-kommandoer?
Eksempelindgang:
foo|dog|cat|mouse|lion|ox|tiger|bar 
Kommentarer
- Angiv nogle eksempler på input.
 
Svar
Næsten der. Sæt bare begge kolonnereferencer ved siden af hinanden.
cat logfile | sed "s/|/ /" | awk "{print $1, $8}" 
 Bemærk også, at du ikke har brug for cat her . 
sed "s/|/ /" logfile | awk "{print $1, $8}" 
 Bemærk også, at du kan fortælle awk, at søjleseparatorerne er | i stedet for mellemrum, så du behøver heller ikke sed. 
awk -F "|" "{print $1, $8}" logfile 
 I henhold til  forslag  af  Caleb , hvis du vil have en løsning, der stadig udsender det sidste felt , selvom der ikke er nøjagtigt otte, kan du bruge $NF. 
awk -F "|" "{print $1, $NF}" logfile 
 Også hvis du vil have output for at bevare | separatorer, i stedet for at bruge et mellemrum kan du angive outputfeltadskillere. Desværre er det “lidt mere klodset end blot at bruge -F -flagget, men her er tre tilgange. 
- 
Du kan tildele input og outputfeltadskillere i
awki BEGIN-blokken.awk "BEGIN {FS = OFS = "|"} {print $1, $8}" logfile - 
Du kan tildele disse variabler, når du ringer til
awkfra kommandolinjen via flagget-v.awk -v "FS=|" -v "OFS=|" "{print $1, $8}" logfile - 
eller simpelthen:
awk -F "|" "{print $1 "|" $8}" logfile 
Kommentarer
-  Godt arbejde med at nedbryde, hvordan dette problem kan forenkles. Du kan tilføje en note om, hvordan du bruger 
|som outputudskiller i stedet for standard plads til streng sammenkædning. Du kan også forklare at bruge$NFi stedet for hårdkodning$8for at få den sidste kolonne. - derefter hvordan opdateres filen?
 -  @pankajprasad Skriv til en ny fil med h 
>skriv derefter den gamle over, eller brugsponge. Dette er dog virkelig et nyt spørgsmål. - @Sparhawk det virker, men reaming-indhold slettes. hvordan skal man håndtere det?
 - @pankajprasad Du skal stille et nyt spørgsmål. Klik på den store blå knap øverst, der siger ” Stil spørgsmål “.
 
Svar
 Du bruger awk alligevel: 
awk "{ print $1, $NF }" file 
Kommentarer
-  Ville ‘ t skal du specificere inputfeltadskilleren (da det i dette tilfælde ser ud til at være 
|snarere det mellemrum) med-F\|eller lignende? Også hvad hvis han ville bruge den samme afgrænser til output? - @Caleb Sandsynligvis: Jeg ventede på, at OP skulle bekræfte, hvordan nøjagtigt input lignede, snarere end at prøve at gæt baseret på de ikke-fungerende eksempler …
 - Bemærk, at det forudsættes, at input indeholder mindst 2 felter.
 - @St é phaneChazelas OP angav tydeligt i kode, at det altid har otte felter.
 - @ michaelb958 Jeg synes ” klart ” overvurderer sagen, bare lidt 🙂
 
Svar
 Erstat bare fra første til sidste | med en | (eller mellemrum hvis du foretrækker det): 
sed "s/|.*|/|/" 
 Bemærk, at selvom der ikke er sed implementering, hvor | er speciel (så længe  udvidet  regelmæssigt udtryk er ikke aktiveret via -E eller  i nogle implementeringer), \| i sig selv er speciel i nogle som GNU sed. Så du bør  ikke  undslippe | hvis du har til hensigt at det skal matche | -tegnet. 
 Hvis du udskifter med mellemrum, og hvis input allerede muligvis indeholder linjer med kun |, skal du behandle det specielt som |.*| vandt ikke match på disse.Det kunne være: 
sed "s/|\(.*|\)\{0,1\}/ /" 
 (det vil sige at .*| -delen er valgfri) Eller: 
sed "s/|.*|/ /;s/|/ /" 
eller:
sed "s/\([^|]*\).*|/\1 /" 
Hvis du vil have det første og det ottende felt uanset antallet af felter i input, så er det bare:
cut -d"|" -f1,8 
   (alle dem vil arbejde med ethvert POSIX-kompatibelt værktøj, forudsat at input danner gyldig tekst (især sed dem fungerer normalt ikke, hvis input har bytes eller sekvenser af bytes, der ikke danner gyldige tegn i det aktuelle sprog som f.eks. printf "unix|St\351phane|Chazelas\n" | sed "s/|.*|/|/" i et UTF-8-sprog)).  
Svar
Hvis du finder dig selv ubehagelig og sed-mindre, kan du opnå samme ting med kerneudstyr:
paste <( cut -d"|" -f1 file) \ <(rev file | cut -d"|" -f1 | rev) 
Kommentarer
-  
cuter renere og mere kompakt end awk / sed, når du bare er interesseret i den første kolonne, eller hvis afgrænsningerne er faste (dvs. ikke et variabelt antal mellemrum). - Temmelig elegant!
 
Svar
 Det ser ud til, at du prøver at få det første og sidste felt i tekst, der er afgrænset af |. 
Jeg antog, at din logfil indeholder teksten som nedenfor,
foo|dog|cat|mouse|lion|ox|tiger|bar bar|dog|cat|mouse|lion|ox|tiger|foo 
Og du vil have output ligesom,
foo bar bar foo 
Hvis ja, så kommer kommandoen til dine “s
Gennem GNU sed,
sed -r "s~^([^|]*).*\|(.*)$~\1 \2~" file 
Eksempel:
$ echo "foo|dog|cat|mouse|lion|ox|tiger|bar" | sed -r "s~^([^|]*).*\|(.*)$~\1 \2~" foo bar 
Kommentarer
- Kolonnerne afgrænses ikke af et rør | men de er i kolonner, jeg er interesseret i at bruge sed, men ikke at bruge kommandoen awk som du gjorde i din kommando: sed -r ‘ s ~ ^ ([^ |] *) . * \ | (. *) $ ~ \ 1 \ 2 ~ ‘ fil
 - ” Kolonnerne er ikke afgrænset af et rør | men de er i kolonner “, mener du kolonner er adskilt af mellemrum?
 - En prøveindgang og en output ville være bedre.
 
Svar
 Du skulle sandsynligvis gøre det med sed – jeg ville alligevel – men bare fordi ingen har skrevet denne endnu: 
while IFS=\| read col1 cols do printf %10s%-s\\n "$col1 |" " ${cols##*|}" done <<\INPUT foo|dog|cat|mouse|lion|ox|tiger|bar INPUT 
OUTPUT
 foo | bar