Ich habe Daten wie diese:
Sample_1 Apples Red
Sample_2 Apples Red
Sample_3 Apples Red
Sample_4 Apples Red
Sample_5 Apples Red
Sample_6 Apples Green
Sample_7 Apples Green
Sample_8 Apples Green
Sample_9 Apples Green
Sample_10 Apples Green
Sample_11 Apples Yellow
Sample_12 Apples Yellow
Sample_13 Apples Yellow
Sample_14 Apples Yellow
Sample_15 Apples Yellow
Wie kann ich die Stichproben aus der ersten Spalte iterativ basierend auf der Kombination der aus den anderen beiden Spalten gebildeten Gruppen ziehen, sodass ich die Stichproben 1–5, 6–10 und 11–15 erhalte?
Was ich letztendlich tun möchte, ist, die Listen der Beispiele (wie die Gruppen oben) als Eingabe für einen anderen Befehl zu ziehen, z. B.:
comm -23 <(sort <all_samples.txt>) <(sort <[input from above]>) > <difference.txt>
Ich habe versucht:
awk '{print $2"\t"$3}' <file.txt> | uniq
Um die eindeutigen Kombinationen der zweiten und dritten Spalte zu erhalten, kann ich damit aber scheinbar nichts anfangen, insbesondere nicht die erste Spalte abrufen, was ich jedoch benötige.
Antwort1
Ist es das, was Sie versuchen?
$ awk '{vals[$2 FS $3] = vals[$2 FS $3] OFS $1} END{for (key in vals) print key vals[key]}' file
Apples Red Sample_1 Sample_2 Sample_3 Sample_4 Sample_5
Apples Green Sample_6 Sample_7 Sample_8 Sample_9 Sample_10
Apples Yellow Sample_11 Sample_12 Sample_13 Sample_14 Sample_15
oder vielleicht das?
$ awk -v fruit='Apples' -v color='Green' '($2==fruit) && ($3==color)' file
Sample_6 Apples Green
Sample_7 Apples Green
Sample_8 Apples Green
Sample_9 Apples Green
Sample_10 Apples Green
Antwort2
Dies ist ein einfaches Beispiel für ein Gawk-Skript, das Ihre Eingabe analysiert und eine für Ihre Anforderungen geeignete Transposition der Daten ausgibt.
#!/usr/bin/gawk -f
# Checks if type (column 2) or subtype (column 3) are
# different from previous line.
(type != $2) || (subtype != $3) {
# Prints the start of a new output line.
# The NR!=1 check avoids that a new line is
# printed on the first line.
printf("%s%s\t%s\t", (NR!=1)?"\n":"", $2, $3);
type=$2;
subtype=$3
}
{
# Prints all sample (column 1) values on the
# current output line.
printf("\"%s\" ", $1);
}
# prints a new line at the end of file.
END{
print "";
}
Die Ausgabe script.awk < input.lst
folgt. Wobei script.awk
sich das vorherige Skript befindet und input.lst
Ihr Eingabebeispiel ist.
Apples Red "Sample_1" "Sample_2" "Sample_3" "Sample_4" "Sample_5"
Apples Green "Sample_6" "Sample_7" "Sample_8" "Sample_9" "Sample_10"
Apples Yellow "Sample_11" "Sample_12" "Sample_13" "Sample_14" "Sample_15"
Die Skriptausgabe kann wie folgt einfach manipuliert werden.
script.awk < input.lst | while read TYPE SUBTYPE LIST
do
echo $TYPE
echo $SUBTYPE
for ITEM in $LIST
do
echo execute some command on $ITEM where type is $TYPE and subtype is $SUBTYPE
done
done
Beachten Sie, dass dieses Skript sehr grob ist. Es gibt beispielsweise keine Fehlerbehandlung und keine Prüfung auf Leerzeichen oder Sonderzeichen in der Eingabe.
Antwort3
Habe es mit dem Below-Skript versucht und es hat gut funktioniert
for i in "Apples"; do for j in "Red" "Green" "Yellow"; do awk -v i="$i" -v j="$j" 'BEGIN{print "Below are table contains" " " i " and " " " j}$2==i && $NF==j{print $0}' filename; done; done
Ausgabe
Below are table contains Apples and Red
Sample_1 Apples Red
Sample_2 Apples Red
Sample_3 Apples Red
Sample_4 Apples Red
Sample_5 Apples Red
Below are table contains Apples and Green
Sample_6 Apples Green
Sample_7 Apples Green
Sample_8 Apples Green
Sample_9 Apples Green
Sample_10 Apples Green
Below are table contains Apples and Yellow
Sample_11 Apples Yellow
Sample_12 Apples Yellow
Sample_13 Apples Yellow
Sample_14 Apples Yellow
Sample_15 Apples Yellow