Wyodrębnij dane z pliku i umieść w różnych plikach na podstawie wartości jednej kolumny


14

Wygenerujemy plik csv o niższych wartościach

yp1234,577,1,3
yp5678,577,3,5
yp9012,132,8,9

Muszę wyodrębnić dane i utworzyć pliki na podstawie drugiej kolumny. Jeśli jest to 577, cała linia musi zostać wyodrębniona i umieszczona w osobnym pliku. Mam na myśli, że potrzebuję pliku z wierszami z drugą kolumną jako samą 577 i innym plikiem z drugą kolumną jako samą 132

Próbowałem użyć IF, ale nie działało


5
Właściwie opublikowanie kodu, który nie działa, jest zawsze dobrym pomysłem.
goldilocks

Odpowiedzi:


27

Użyj awk:

awk -F, '{ print > $2 ".csv" }' file.csv

Spowoduje to utworzenie dwóch plików 577.csv, a 132.csvw bieżącym katalogu.

Powyższe polecenie zakłada, że ​​możesz mieć tylko 132lub 577drugie pole. Utworzy jedną nazwę pliku dla każdej wartości znalezionej w drugim polu całości file.csv.

Jeśli oprócz dwóch, które Cię interesują, są inne wartości i chcesz zignorować te linie, zrób to zamiast tego:

awk -F, '$2 == "577" || $2 == "132" { print > $2 ".csv" }' file.csv

1
Istnieją błędne awkimplementacje, których nie można użyć print > $2 ".cvs". Na tych, trzeba by pierwszy obliczyć nazwę pliku, a następnie wykonaj print: fname = $2 ".cvs"; print > fname.
Kusalananda

3

Podoba mi się awkrozwiązanie Terdona , ale ze względu na kompletność, tutaj jest tylko sugestiabash

while IFS=, read -r a1 a2 a3 a4; do 
    echo "$a1,$a2,$a3,$a4" >> "$a2".csv
done < file.csv

Będzie produkować pliki 577.csvoraz 132.csvw bieżącym katalogu.


3

Aby wyodrębnić wszystkie 577 na standardowe wyjście

grep -e '^.*,577,.*,.*$' youfile.csv >result_extract_557.csv

- edytuj 1 Poprawiony, w oparciu o komentarz @ terdon poniżej, aby uniknąć fałszywych dopasowań, gdy co najmniej 3 przecinki na linii z 577.

grep -e '^[:alnum:]*,577,[:digit:]*,[:digit:]*$' youfile.csv >result_extract_557.csv

Myślę jednak, że jego awkrozwiązanie jest bardziej kompleksowe.


Będzie to pasować, nawet jeśli 577 znajduje się na innym polu, a nie na drugim polu lub jeśli jest częścią pola. Na przykład foo577barlub yp9012,132,8,577.
terdon

Myślałem, że moje przecinki zależą od pozycji pola?
X Tian

Przepraszam, podałem złe przykłady, ale .*można również dopasować przecinki, więc nie wiesz, które pole jest dopasowane. Może być drugi, może być również 45. Moja druga skarga była błędna, masz rację, że przecinki chronią przed dopasowaniem foo577bar.
terdon

co zrobić, jeśli | znak jest używany zamiast,.
user3116123

pojawia się poniżej błędu grep: niedozwolona opcja - e Zastosowanie: grep -hblcnsviw plik sygnatur. . .
user3116123

1

Używanie csvkit:

$ csvgrep -c 2 -m 577 data.csv >output.csv

Te -c 2marki cvsgreprozważyć drugą kolumnę iz -m 577pytamy go dopasować ciąg 577w tej kolumnie.

Do output.csv:

yp1234,577,1,3
yp5678,577,3,5

Aby dopasować liczbę ciągów i zapisać dane wyjściowe w pliku dla każdego ciągu:

for pattern in 577 132; do
  csvgrep -c 2 -m "$pattern" data.csv >"output-$pattern.csv"
done

Spowoduje to utworzenie dwóch plików output-132.csvi output-577.csv.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.