1-й столбец в inFile содержит строку, которая не обязательно присутствует во всех inFile
2-й и 7-й столбцы в каждом inFile содержат строки Title#
Используя AWK, я не могу правильно собрать это воедино. Надеюсь, использование описательных переменных поможет прояснить, что я пытаюсь сделать. Вот компоненты, которые, как мне кажется, мне нужны:
- входные файлы, разделенные табуляцией:
-F'\t'
- увеличьте строки в 1-м столбце, но добавьте каждое «имя» только один раз в «1stColumnNames»:
!1stColumnNames[$1]++ { name[++i] = $1 }
- создайте новый индекс для каждого файла .tsv, чтобы хранить значения для каждого файла, чтобы избежать перезаписи значений каждого столбца:
!r[FILENAME]++ { ++argind }
- сохранить соответствующие значения столбцов во 2-м и 7-м столбцах для каждого файла:
{ 2ndColumnVals[$1, argind] = $2 } { 7thColumnVals[$1, argind] = $7 }
- распечатать все 1stColumnNames со связанными 2ndColumnVals и 7thColumnVals, включая их заголовки «Title1», «Title2», «Title3» и т. д.:
?????
- значения индекса, которые были пустыми для определенного 2ndColumnVals или 7thColumnVals, печатаются как Mtee:
?????
- сделайте это для всех файлов .tsv в текущем рабочем каталоге и выведите новый файл tsv:
*.tsv > outFile.tsv
Примеры файлов
inFile1.tsv
Names Title1 Title2
AAAA 1111 123456
BBBBB 1111 123456
CCC 1111 123456
inFile2.tsv
Names Title3 Title4
BBBBB 2222 789456
DDDDD 2222 789456
EEEE 2222 789456
inFile3.tsv
Names Title5 Title6
AAAA 3333 987654
CCC 3333 987654
EEEE 3333 987654
outFile123.tsv
Names Title1 Title2 Title3 Title4 Title5 Title6
AAAA 1111 123456 Mtee Mtee 3333 987654
BBBBB 1111 123456 2222 789456 Mtee Mtee
CCC 1111 123456 Mtee Mtee 3333 987654
DDDDD Mtee Mtee 2222 789456 Mtee Mtee
EEEE Mtee Mtee 2222 789456 3333 987654
Тестовый сценарий
GNU Awk 4.0.1 находится в /usr/bin/awk, поэтому я создал этот файл и запустил его в том же рабочем каталоге, где расположены 3 входных файла:
named as script1.sh#### Example Usage: script1.sh inFile1.tsv inFile2.tsv inFile3.tsv > outFile123.tsv
awk -F'\t' '
FNR==1 { ++numFiles}
!seen[$1]++ { keys[++numKeys] = $1 }
{ a[$1,numFiles] = $2 FS $3 }
END {
for (keyNr=1; keyNr<=numKeys; keyNr++) {
key = keys[keyNr]
printf "%s", key
for (fileNr=1;fileNr<=numFiles;fileNr++) {
printf "\t%s", ((key,fileNr) in a ? a[key,fileNr] : "Mtee\tMtee")
}
print ""
}
}
' "$@"
Запуск awk -F script1.awk inFile1.tsv inFile2.tsv inFile3.tsv > outFile123.tsv
выводит следующие сообщения об ошибках:
awk: cmd. line:1: inFile1.tsv
awk: cmd. line:1: ^ syntax error
Тестовый скрипт 2 из konsolebox
работает отлично, но я пытаюсь понять каждую строку, комментируя:
#!/usr/bin/awk -f
#### named as script2.awk
#### Example Usage: awk -f script2.awk inFile1.tsv inFile2.tsv inFile3.tsv > outFile123.tsv
BEGIN { FS = "\t" } #input File Style is tab-delimited
{ sub(/\r/, "") } #remove all carriage return characters
!f[FILENAME]++ { ++indx } #for all files inputted make a single index called indx
!a[$1]++ { keys[i++] = $1 } #the new indx comprises only unique strings in column 1
{ b[$1, indx] = $2 FS $3 } #the 2nd and 3rd column are tab delimited and each pair that corresponds to a string saved in keys gets stored after the 1st column string in matrix b
END {
for (i = 0; i in keys; ++i) { #????
key = keys[i] #????
printf "%s", keys #prints out all strings in the index column 1 stored as keys
for (j = 1; j <= indx; ++j) { #????
v = b[key, j] #????
printf "\t%s", length(v) ? v : "Mtee" FS "Mtee" #print out strings as tab delimited and replace any lengths of 1 char to two Mtee separated by a tab
}
print "" #????
}
}
script1.awk
НЕ является сценарием awk, это сценарий оболочки, который вызывает awk. Переименуйте его вscript1.sh
для ясности, сделайте его исполняемым, как и любой другой сценарий оболочки, добавьте"$@"
в конец сценария awk, чтобы оболочка передала awk свой список аргументов, а затем выполните его какscript1.sh inFile1.tsv inFile2.tsv inFile3.tsv > outFile123.tsv
. Я отредактировал ваш вопрос, чтобы показать это. - person Ed Morton   schedule 31.07.2014