2012-11-14 21 views
7

Mam plik o nazwie 'plainlinks', które wygląda następująco:Powtarzanie tekstu między dwoma ciągami? (? Awk sed?)

13080. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94092-2012.gz 
13081. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94094-2012.gz 
13082. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94096-2012.gz 
13083. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94097-2012.gz 
13084. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94098-2012.gz 
13085. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94644-2012.gz 
13086. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94645-2012.gz 
13087. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94995-2012.gz 
13088. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-94996-2012.gz 
13089. ftp://ftp3.ncdc.noaa.gov/pub/data/noaa/999999-96404-2012.gz 

muszę produkować wyjście, które wygląda tak:

999999-94092 
999999-94094 
999999-94096 
999999-94097 
999999-94098 
999999-94644 
999999-94645 
999999-94995 
999999-94996 
999999-96404 

Odpowiedz

11

Korzystanie sed:

sed -E 's/.*\/(.*)-.*/\1/' plainlinks 

wyjściowa:

999999-94092 
999999-94094 
999999-94096 
999999-94097 
999999-94098 
999999-94644 
999999-94645 
999999-94995 
999999-94996 
999999-96404 

Aby zapisać zmiany w pliku należy wybrać opcję -i:

sed -Ei 's/.*\/(.*)-.*/\1/' plainlinks 

lub zapisać do nowego pliku, a następnie przekierować:

sed -E 's/.*\/(.*)-.*/\1/' plainlinks > newfile.txt 

Objaśnienie:

s/ # subsitution 
.* # match anything 
\/ # upto the last forward-slash (escaped to not confused a sed) 
(.*) # anything after the last forward-slash (captured in brackets) 
-  # upto a hypen 
.* # anything else left on line 
/ # end match; start replace 
\1 # the value captured in the first (only) set of brackets 
/ # end 
+1

Dzięki tona że zrobił to –

4

Zakładając, że Format pozostaje niezmieniony zgodnie z opisem, można to zrobić za pomocą awk:

awk 'BEGIN{FS="[/-]"; OFS="-"} {print $7, $8}' plainlinks > output_file 

wyjściowa:

999999-94092 
999999-94094 
999999-94096 
999999-94097 
999999-94098 
999999-94644 
999999-94645 
999999-94995 
999999-94996 
999999-96404 

Wyjaśnienie:

  • awk czyta plik wejściowy jednej linii na raz, łamiąc każdy wiersz w "polach"
  • 'BEGIN{FS="[/-]"; OFS="-"} określa, że ​​ogranicznik użyte na liniach wejściowych powinny być: / lub -, ale także określa, że ​​wyjście powinno być ograniczone przez -
  • {print $7, $8}' awk wydrukować 7 i 8 pole każdej linii, w tym przypadku 999999 i 9xxxx
  • plainlinks jest gdzie nazwa pliku wejściowego będzie iść
  • > output_file przekierowuje dane wyjściowe do pliku o nazwie output_file
4

Tylko z interpretacji parametrów przez powłokę:

while IFS= read -r line; do 
    tmp=${line##*noaa/} 
    echo ${tmp%-????.gz} 
done < plainlinks 
7

Dla zabawy.

awk -F\/ '{print substr($7,0,12)}' plainlinks

lub grep

grep -Eo '[0-9]{6}-[0-9]{5}' plainlinks

+1

+1 dla prostszego rozwiązania grep. –

+0

@ sudo_o dobrze dzięki, +1 za rozwiązanie. za bycie pierwszym. – matchew

+0

zgodził się, +1 dla eleganckiego rozwiązania grep –

1

Jeśli format pozostaje taka sama, nie ma potrzeby sed lub awk:

cat your_file | cut -d "/" -f 7- | cut -d "-" -f 1,2 
+0

Jeśli format nie jest taki sam, rozwiązania sed i awk będą łamać się tak samo. :) – Kaz