ich zwei ascii Tabellen verketten möchte (untereinander) der Anteil einige, aber nicht alle Spaltenüberschriften, und ich will „blanks“ mit einigen Zeichenfolge ersetzen, wie „nan“ in der Ausgabe. (Bezogen: can we do this with emacs, aber keine Antwort, als der noch)Concatenate ascii/org Tabellen mit einigen verschiedenen Rubriken
z.B.
Tabelle 1
Head1 HeadA
1 a
2 b
Tabelle 2
HeadA HeadFoo
c bar
Und das Ergebnis wäre
Head1 HeadA HeadFoo
1 a nan
2 b nan
nan c bar
ich die folgende sehr frisch zsh Skript geschrieben haben (verwendet ein zsh-only-Befehl) aber es ist langsam wenn es viele Spalten gibt (für ob Gründe).
Beachten Sie, dass oben Ich benutze Tab-separierte Beispiele, aber mein Skript erwartet durch Leerzeichen getrennte Tabellen.
#!/bin/zsh
#
# take several dat files, possibly with different headers
#
containsElement() {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
ALL_COLUMNS=()
for A in "[email protected]"; do
if [ ! -f ${A} ]
then
echo not a file
exit
fi
ALL_COLUMNS=("${ALL_COLUMNS[@]}" `head -1 "${A}"`)
done
typeset -U ALL_COLUMNS
echo $ALL_COLUMNS
for A in "[email protected]"; do
HEADER=($(head -1 "${A}"))
TMP="_TMP_${A}_"
TMPFILE="_TMPFILE"
#create empty temporary files (/hack)
touch "${TMPFILE}"
touch "${TMP}"
rm "${TMP}"
rm "${TMPFILE}"
touch "${TMPFILE}"
touch "${TMP}"
for C in ${ALL_COLUMNS[@]}; do
if ! containsElement "${C}" "${HEADER[@]}"
then
"${C}" not in "${HEADER[@]}"
#paste a column of nans to TMPFILE
paste "${TMP}" <(sed '1d;s/.*/nan/' "${A}") > "${TMPFILE}"
cat "${TMPFILE}" > "${TMP}"
else
# echo "${C}" is in "${HEADER[@]}"
#find which column this is, cut it, and paste it to TMPFILE
COUNT=1
for H_KEY in $(head -1 ${A}); do
if [ "${C}" = "${H_KEY}" ]; then
break
else
let COUNT=COUNT+1
fi
done
paste "${TMP}" <(cut -d " " -f${COUNT} <(sed '1d' ${A})) > "${TMPFILE}"
cat "${TMPFILE}" > "${TMP}"
fi
done
#cat the current input file to stdout, with any additional nan columns.
#remove leading white space left by paste
sed 's/^[[:space:]]*//' "${TMP}"
rm "${TMP}"
done
Bearbeiten: Hier sind zwei weitere Eingabedateien (Leerzeichen diesmal begrenzt) zu versuchen.
% cat test1.dat
A B C
1 2 3
% cat test2.dat
A B D
1 2 4
% ./collate_dat_files_different_headers.sh test2.dat test1.dat
A B D C
1 2 4 nan
1 2 nan 3
Und hier ist es, eine größere Menge von Eingaben (beachten Sie die Leerzeichen getrennte Eingänge, wenn Sie dies versuchen, auf Ihr eigenes Skript aus.):
% ROWS=10; (echo A B C D E F G && seq $ROWS > _tmp && paste _tmp _tmp _tmp _tmp _tmp _tmp _tmp | sed 's/\t/ /g') > bigtest.dat
% cat bigtest.dat
A B C D E F G
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
4 4 4 4 4 4 4
5 5 5 5 5 5 5
6 6 6 6 6 6 6
7 7 7 7 7 7 7
8 8 8 8 8 8 8
9 9 9 9 9 9 9
10 10 10 10 10 10 10
% cut -d" " -f1,2,5,7 bigtest.dat > bigtest1.dat
% cut -d" " -f1,2,4,7 bigtest.dat > bigtest2.dat
% cut -d" " -f1,2 bigtest.dat > bigtest3.dat
% cut -d" " -f7,6,4,2,3,1 bigtest.dat > bigtest4.dat
% ./collate_dat_files_different_headers.sh bigtest1.dat bigtest2.dat bigtest3.dat bigtest4.dat
A B E G D C F
1 1 1 1 nan nan nan
2 2 2 2 nan nan nan
3 3 3 3 nan nan nan
4 4 4 4 nan nan nan
5 5 5 5 nan nan nan
6 6 6 6 nan nan nan
7 7 7 7 nan nan nan
8 8 8 8 nan nan nan
9 9 9 9 nan nan nan
10 10 10 10 nan nan nan
1 1 nan 1 1 nan nan
2 2 nan 2 2 nan nan
3 3 nan 3 3 nan nan
4 4 nan 4 4 nan nan
5 5 nan 5 5 nan nan
6 6 nan 6 6 nan nan
7 7 nan 7 7 nan nan
8 8 nan 8 8 nan nan
9 9 nan 9 9 nan nan
10 10 nan 10 10 nan nan
1 1 nan nan nan nan nan
2 2 nan nan nan nan nan
3 3 nan nan nan nan nan
4 4 nan nan nan nan nan
5 5 nan nan nan nan nan
6 6 nan nan nan nan nan
7 7 nan nan nan nan nan
8 8 nan nan nan nan nan
9 9 nan nan nan nan nan
10 10 nan nan nan nan nan
1 1 nan 1 1 1 1
2 2 nan 2 2 2 2
3 3 nan 3 3 3 3
4 4 nan 4 4 4 4
5 5 nan 5 5 5 5
6 6 nan 6 6 6 6
7 7 nan 7 7 7 7
8 8 nan 8 8 8 8
9 9 nan 9 9 9 9
10 10 nan 10 10 10 10
Meine Frage: Gibt es eine schnellere/bessere Möglichkeit, dies zu tun oder Verbesserungen an meinem Skript?
Haben Sie bei 'paste' sah, 'Join' oder' Spalte'? – LinuxDisciple
Ich glaube nicht, Join ist, was ich will, da es Tabellen zusammenführen wird, anstatt sie zu katzen. Paste ist in meinem Skript oben, und Spalte kann hilfreich sein beim Zusammenfügen von Dingen (wie Paste ist), aber ich sehe nicht, wie es das Skript beschleunigen wird. Gut zu wissen über diese obwohl. – Alejandro
Sollte nicht das letzte * Ergebnis * "nan c bar" sein ?? –